你如何阅读scanf直到C中的EOF?
我有这个,但一旦达到假定的EOF,它只是重复循环和scanf。
int main(void) { char words[16]; while(scanf("%15s", words) == 1) printf("%s\n", words); return 0; }
尝试:
while(scanf("%15s", words) != EOF)
您需要将scanf
输出与EOF
进行比较
由于您在格式字符串中指定宽度为15
,因此最多可读取15个字符。 所以char数组的单词大小应为16
( null
char为15 +1
)。 所以声明为:
char words[16];
Scanf几乎总是比它的价值更麻烦。 以下是两种更好的方法来做你想做的事情。 第一个是对代码的或多或少的直接翻译。 它更长,但你可以看一下它,看清楚它的作用,与scanf不同。
#include #include int main(void) { char buf[1024], *p, *q; while (fgets(buf, 1024, stdin)) { p = buf; while (*p) { while (*p && isspace(*p)) p++; q = p; while (*q && !isspace(*q)) q++; *q = '\0'; if (p != q) puts(p); p = q; } } return 0; }
这是另一个版本。 通过检查看到它的作用有点困难,但如果一行超过1024个字符,它就不会中断,所以这是我在生产中使用的代码。 (好吧,我在制作中真正使用的是tr -s '[:space:]' '\n'
,但这就是你实现类似的东西。)
#include #include int main(void) { int ch, lastch = '\0'; while ((ch = getchar()) != EOF) { if (!isspace(ch)) putchar(ch); if (!isspace(lastch)) putchar('\n'); lastch = ch; } if (lastch != '\0' && !isspace(lastch)) putchar('\n'); return 0; }
您的代码循环直到它读取单个单词,然后退出。 因此,如果你给它多个单词,它将读取第一个并退出,而如果你给它一个空输入,它将永远循环。 无论如何,它只会从未初始化的内存中打印随机垃圾。 这显然不是你想要的,但你想要什么? 如果您只想阅读并打印第一个单词(如果存在),请使用if:
if (scanf("%15s", word) == 1) printf("%s\n", word);
如果你想循环只要你能读一个单词,使用while:
while (scanf("%15s", word) == 1) printf("%s\n", word);
另外,正如其他人所说,你需要为单词数组提供一个足够大的scanf大小:
char word[16];
其他人建议测试EOF而不是检查scanf匹配的项目数。 这种情况很好,除非有EOF,否则scanf不能匹配,但在其他情况下(例如尝试读取整数)则不太好,其中scanf可能在没有达到EOF的情况下匹配任何内容(如果输入不是’数字)并返回0。
编辑
看起来你改变了你的问题以匹配我运行它时工作正常的代码 – 循环读取单词直到达到EOF然后退出。 所以你的代码还有其他的东西,或许与你如何按照大卫的建议提供输入有关
您需要检查EOF
的返回值,而不是1
。
请注意,在您的示例中,您还使用了两个不同的变量名称, words
和word
,仅声明了words
,并且未声明其长度,应该为16以适合读入的15个字符加上NUL
字符。
我想最好的办法就是……
int main() { char str[100]; scanf("[^EOF]",str); printf("%s",str); return 0; }
对于C用户,这也可以
while ( gets(str) != NULL )