【发布时间】:2025-11-26 04:50:01
【问题描述】:
我试图在 C 中输入一个完整的行。最初我这样做了,
char line[100] // assume no line is longer than 100 letters.
scanf("%s", line);
忽略安全漏洞和缓冲区溢出,我知道这永远不会超过一个单词输入。我又修改了,
scanf("[^\n]", line);
当然,这不能超过一行输入。然而,下面的代码却陷入了无限循环,
while(fscanf(stdin, "%[^\n]", line) != EOF)
{
printf("%s\n", line);
}
这是因为,\n 从未被消耗过,并且会反复停在同一点并在 line 中具有相同的值。所以我将代码重写为,
while(fscanf(stdin, "%[^\n]\n", line) != EOF)
{
printf("%s\n", line);
}
这段代码工作无可挑剔(或者我是这么认为的),用于文件输入。但是对于来自stdin 的输入,这会产生神秘、怪异、口齿不清的行为。只有在输入第二行后,才会打印第一行。我无法理解到底发生了什么。
我正在做的就是这个。记下字符串,直到遇到\n,将其存储在line 中,然后从输入缓冲区中使用\n。现在打印这个line 并准备好输入下一行。还是我被误导了?
然而,在发布这个问题时,我找到了一个更好的选择,
while(fscanf(stdin, "%[^\n]%*c", line) != EOF)
{
printf("%s\n", line);
}
这适用于所有情况。但我的问题仍然存在。这段代码怎么来的,
while(fscanf(stdin, "%[^\n]\n", line) != EOF)
{
printf("%s\n", line);
}
适用于来自文件的输入,但会导致来自标准输入的输入出现问题?
【问题讨论】:
-
使用 fgets(),而不是 fscanf()。
-
我也会选择
fgets- 不要忘记它会保留任何尾随newline。至于scanf家族,请始终检查正确的转换的项目数。0转换的项目不会被EOF测试检测到,但如果没有转换正确数量的项目,EOF会检测到。 -
不要爬山,绕着它走。
scanf家庭停滞不前时很可怕。最好使用fgets阅读该行,然后然后 使用sscanf。 -
您的 sn-ps 仍在测试返回的
EOF。这只会在任何错误输入时停止。如果您正在读取文件并且没有获得正确的数据,那么您不妨认输——GIGO——但测试EOF会导致停顿。坏数据留在那里等待以某种方式读取或删除,但它不是文件的结尾。while(scanf("...", ...) == numberofitems) {...} -
@FredK,永远不要使用
gets()1) 它会导致输入缓冲区溢出,2) 它不再是 C 语言的一部分——现代编译器会警告你不要使用 @987654347 @