在while循环中使用scanf

Tyl*_*ock 12 c equality scanf while-loop

这个非常简单的问题可能是一个非常简单的答案:

我正在阅读Pratta的"C Primer Plus",他一直在使用这个例子

while (scanf("%d", &num) == 1)...
Run Code Online (Sandbox Code Playgroud)

== 1真的有必要吗?似乎可以写一下:

while (scanf("%d", &num))
Run Code Online (Sandbox Code Playgroud)

似乎相等测试是不必要的,因为scanf返回读取的对象数,1将使while循环成为真.是确保读取的元素数量正好为1还是完全多余的原因?

JRL*_*JRL 26

在C中,0被评估为false,其他一切被评估为true.因此,如果scanf返回EOF,这是一个负值,则循环将评估为true,这不是您想要的.


RBe*_*eig 10

由于scanf在文件末尾返回值EOF(-1),因此写入的循环是正确的.只要输入包含匹配的文本,它就会运行%d,并在第一个不匹配或文件结束时停止.

如果scanf期待不止一个输入,那么一眼就会更加清晰......

while (scanf("%d %d", &x, &y)==2) { ... }
Run Code Online (Sandbox Code Playgroud)

当第一次无法匹配两个值时,将退出循环,这可能是由于文件结束(scanf返回EOF(-1))或输入匹配错误(例如输入xyzzy 42不匹配%d %d所以scanf停止第一次失败并返回0 而不写入任何一个xy)当它返回一些小于2的值时.

当然,scanf不是从正常人解析实际输入时,你的朋友.处理错误案件有很多陷阱.

编辑:更正错误:在文件末尾scanf返回EOF,或者计算成功设置的变量数的非负整数.

关键点在于,由于任何非零值都TRUE在C中,因此无法在循环中正确测试返回值,这很容易导致意外行为.特别是,while(scanf(...))除非遇到无法根据其格式转换的输入文本,否则是无限循环.

我不能强调足够强烈认为scanf不是你的朋友.对于一些简单的解析来说,组合fgets并且sscanf可能足够,但即使这样,它也很容易被边缘情况和错误所淹没.