在C语言中如何读取scanf直到EOF?
我有这个,但是一旦它到达假定的 EOF,它就会再次重复循环和 scanf 。
int main(void)
{
char words[16];
while(scanf("%15s", words) == 1)
printf("%s\n", words);
return 0;
}
I have this but once it reaches the supposed EOF it just repeats the loop and scanf again.
int main(void)
{
char words[16];
while(scanf("%15s", words) == 1)
printf("%s\n", words);
return 0;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
尝试:
您需要将
scanf
输出与EOF
进行比较,因为您在格式字符串中指定了
15
的宽度,所以您最多会读取15 个字符。因此,单词 char 数组的大小应为16
(15 +1
对于null
char)。所以将其声明为:Try:
You need to compare
scanf
output withEOF
Since you are specifying a width of
15
in the format string, you'll read at most 15 char. So the words char array should be of size16
(15 +1
fornull
char). So declare it as:您的代码会循环直到读取一个单词,然后退出。因此,如果你给它多个单词,它会读取第一个单词并退出,而如果你给它一个空输入,它将永远循环。无论如何,它只会打印未初始化内存中的随机垃圾。这显然不是你想要的,但是你想要什么?如果您只想读取并打印第一个单词(如果存在),请使用 if:
如果您想循环只要可以读取一个单词,请使用 while:
另外,正如其他人指出的那样,您需要给出该单词数组的大小对于你的 scanf 来说足够大:
其他人建议测试 EOF 而不是检查 scanf 匹配的项目数。对于这种情况来说这很好,除非有 EOF,否则 scanf 不会失败,但在其他情况下(例如尝试读取整数)则不太好,其中 scanf 可能在未达到 EOF 的情况下不匹配任何内容(如果输入不是) t 一个数字)并返回 0。
编辑
看起来你改变了你的问题以匹配我的代码,当我运行它时,它工作得很好——循环读取单词,直到达到 EOF,然后退出。所以你的代码发生了其他事情,可能与你如何按照大卫的建议向其提供输入有关
Your code loops until it reads a single word, then exits. So if you give it multiple words it will read the first and exit, while if you give it an empty input, it will loop forever. In any case, it will only print random garbage from uninitialized memory. This is apparently not what you want, but what do you want? If you just want to read and print the first word (if it exists), use if:
If you want to loop as long as you can read a word, use while:
Also, as others have noted, you need to give the word array a size that is big enough for your scanf:
Others have suggested testing for EOF instead of checking how many items scanf matched. That's fine for this case, where scanf can't fail to match unless there's an EOF, but is not so good in other cases (such as trying to read integers), where scanf might match nothing without reaching EOF (if the input isn't a number) and return 0.
edit
Looks like you changed your question to match my code which works fine when I run it -- loops reading words until EOF is reached and then exits. So something else is going on with your code, perhaps related to how you are feeding it input as suggested by David
Scanf 带来的麻烦几乎总是大于它的价值。这里有两种更好的方法来完成您想要做的事情。第一个或多或少是代码的直接翻译。它更长,但您可以查看它并清楚地看到它的作用,这与 scanf 不同。
这是另一个版本。通过检查很难看出它的作用,但如果一行长度超过 1024 个字符,它不会中断,所以这是我在生产中使用的代码。 (嗯,实际上我在生产中使用的是
tr -s '[:space:]' '\n'
,但这就是实现类似内容的方式。 )Scanf is pretty much always more trouble than it's worth. Here are two better ways to do what you're trying to do. This first one is a more-or-less direct translation of your code. It's longer, but you can look at it and see clearly what it does, unlike with scanf.
And here's another version. It's a little harder to see what this does by inspection, but it does not break if a line is longer than 1024 characters, so it's the code I would use in production. (Well, really what I would use in production is
tr -s '[:space:]' '\n'
, but this is how you implement something like that.)伙计,如果您使用的是 Windows,则不能通过按 Enter 来到达
EOF
,而是通过在控制台上按 Crtl+Z 来到达。这将打印“^Z”,这是EOF
的指示符。读取此内容时函数的行为(EOF
或 Crtl+Z):scanf(...)
EOF
gets(<变量>)
NULL
feof(stdin)
1
>getchar()
EOF
Man, if you are using Windows,
EOF
is not reached by pressing enter, but by pressing Crtl+Z at the console. This will print "^Z", an indicator ofEOF
. The behavior of functions when reading this (theEOF
or Crtl+Z):scanf(...)
EOF
gets(<variable>)
NULL
feof(stdin)
1
getchar()
EOF
您需要根据
EOF
检查返回值,而不是根据1
。请注意,在您的示例中,您还使用了两个不同的变量名称,
words
和word
,仅声明了words
,并没有声明其长度,它应该是 16 以适合读入的 15 个字符加上一个NUL
字符。You need to check the return value against
EOF
, not against1
.Note that in your example, you also used two different variable names,
words
andword
, only declaredwords
, and didn't declare its length, which should be 16 to fit the 15 characters read in plus aNUL
character.我想做到这一点的最好方法是......
I guess best way to do this is ...
对于 C 用户,这也适用
For C users, this will also work