替換:
for (int i = 0; i < 50; i++) {
for (int k = 0; k < 50; k++) {
fscanf(cola, "%c", &buff);
array[i][k] = buff;
}
}
有:
for (int i = 0; i < 50; i++) {
for (int k = 0; k < 50; k++) {
int c = getc(cola);
if (c == EOF)
break;
array[i][k] = c;
}
}
由於buff
是那麼不使用,不定義它。請注意,返回類型getc()
是int
,而不僅僅是char
。總是檢查I/O功能是否成功/失敗。在您的原始代碼中,您甚至不檢查I/O操作是否成功,這使得檢測EOF成爲不可能。
請注意,此代碼提出了許多可能或可能不合理的假設。例如,你假設文件中的每一行由49個字符和一個換行符組成;你也假設你永遠不需要把信息打印成'字符串'(你現有的代碼不會;它會逐個字符地打印,所以它是'安全的')。
你可能想描述輸入爲:
- 閱讀多達50行最多49個字符加在每行換行,並將結果存儲在變量
array
每行是一個空值終止字符串。
這對常見問題(短行,長行,沒有足夠的行)更具彈性。該代碼可能是:
enum { LINE_LEN = 50, NUM_LINES = 50 };
char array[NUM_LINES][LINE_LEN];
int i;
for (i = 0; i < LINE_LEN; i++)
{
int c;
int k;
for (k = 0; k < LINE_LEN; k++)
{
c = getc(cola);
if (c == EOF || c == '\n')
break;
if (k == LINE_LEN - 1)
{
/* Too long - gobble excess */
while ((c = getc(cola)) != EOF && c != '\n')
;
break;
}
array[i][k] = c;
}
array[i][k] = '\0';
if (c == EOF)
break;
}
int num_lines = i; // You have num_lines lines of data in your array
我發現可口可樂™ASCII藝術形象的一個版本https://www.ascii-code.com/ascii-art/logos/coca-cola.php這類似於你在你的圖片是什麼,但也有許多其他來源及其變體:
__ ___ __ .ama ,
,d888a ,d88888888888ba. ,88"I) d
a88']8i a88".8"8) `"8888:88 " _a8'
.d8P' PP .d8P'.8 d) "8:88:baad8P'
,d8P' ,ama, .aa, .ama.g ,mmm d8P' 8 .8' 88):888P'
,d88' d8[ "8..a8"88 ,8I"88[ I88' d88 ]IaI" d8[
a88' dP "bm8mP8'(8'.8I 8[ d88' `" .88
,88I ]8' .d'.8 88' ,8' I[ ,88P ,ama ,ama, d8[ .ama.g
[88' I8, .d' ]8, ,88B ,d8 aI (88',88"8) d8[ "8. 88 ,8I"88[
]88 `888P' `8888" "88P"8m" I88 88[ 8[ dP "bm8m88[.8I 8[
]88, _,,aaaaaa,_ I88 8" 8 ]P' .d' 88 88' ,8' I[
`888a,. ,aadd88888888888bma. )88, ,]I I8, .d')88a8B ,d8 aI
"888888PP"' `8""""""8 "888PP' `888P' `88P"88P"8m"
此文件最長的行是第一個在67個字符加上換行符;最短的是61個字符加換行符。該文件總共只有13行和845個字符(LF行尾)。因此,你的程序不適合處理這個特定的數據文件。它看起來有2,500個字符,並且不會得到它們。
我的完整測試代碼被人做了手腳從標準輸入讀取數據,而不是一個固定的文件名。
#include <stdio.h>
int main(void)
{
FILE *cola = stdin;
enum { LINE_LEN = 80, NUM_LINES = 50 };
char array[NUM_LINES][LINE_LEN];
int i; // Need value of i after loop
for (i = 0; i < NUM_LINES; i++)
{
int c; // Need value of c after loop
int k;
for (k = 0; k < LINE_LEN; k++)
{
c = getc(cola);
if (c == EOF || c == '\n')
break;
if (k == LINE_LEN - 1)
{
/* Too long - gobble excess */
while ((c = getc(cola)) != EOF && c != '\n')
;
break;
}
array[i][k] = c;
}
array[i][k] = '\0';
if (c == EOF)
break;
}
int num_lines = i; // You have num_lines lines of data in your array
for (i = 0; i < num_lines; i++)
puts(array[i]);
return 0;
}
我在顯示的數據文件上測試了它,最後一行是空行,並且在空白行後面包含了超過79個字符的幾行。它正確處理所有這些特殊情況。請注意,處理用戶輸入很難;處理不正當的用戶輸入是困難的。代碼不太緊湊。您可以更改規則,然後更改代碼以匹配。我不確定這是編碼這個最簡單的方法;它確實有效,但是。有一個函數來處理內部輸入循環可能會更好;外部循環可以測試該函數的返回值。這將減少特殊情況的處理。
#include <assert.h>
#include <limits.h>
#include <stdio.h>
static int read_line(FILE *fp, size_t buflen, char *buffer)
{
assert(buflen < INT_MAX);
int c; // Need value of c after loop
size_t k; // Need value of k after loop
for (k = 0; k < buflen; k++)
{
if ((c = getc(fp)) == EOF || c == '\n')
break;
if (k == buflen - 1)
{
/* Too long - gobble excess */
while ((c = getc(fp)) != EOF && c != '\n')
;
break;
}
buffer[k] = c;
}
buffer[k] = '\0';
return (k == 0 && c == EOF) ? EOF : (int)k;
}
int main(void)
{
enum { LINE_LEN = 80, NUM_LINES = 50 };
char array[NUM_LINES][LINE_LEN];
int i;
for (i = 0; i < NUM_LINES; i++)
{
if (read_line(stdin, LINE_LEN, array[i]) == EOF)
break;
}
int num_lines = i;
for (i = 0; i < num_lines; i++)
puts(array[i]);
return 0;
}
這會產生與以前版本相同輸入的相同輸出。
請不要發表圖片的代碼。相反,創建一個包含實際代碼的代碼塊。 –
檢查'fscanf'的返回值。 – BLUEPIXY
我現在編輯我的文章。 –