替换:
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
我现在编辑我的文章。 –