代码之家  ›  专栏  ›  技术社区  ›  Tyler Brock

在while循环中使用scanf

  •  11
  • Tyler Brock  · 技术社区  · 14 年前

    对于这个极其简单的问题,可能有一个极其简单的答案:

    我在读普拉塔的《初级读物》他一直在用这个例子

    while (scanf("%d", &num) == 1)...
    

    while (scanf("%d", &num))
    

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

    5 回复  |  直到 11 年前
        1
  •  26
  •   JRL    14 年前

    在C中,0的值为false,其他值为true。因此,如果scanf返回EOF,这是一个负值,则循环的计算结果将为true,这不是您想要的结果。

        2
  •  10
  •   RBerteig Keith Adler    14 年前

    scanf 返回文件末尾的值EOF(即-1),则循环写入正确。只要输入包含匹配的文本,它就会运行 %d ,并在第一个不匹配或文件结尾处停止。

    一眼就能看清楚 我们期待不止一个输入。。。。

    while (scanf("%d %d", &x, &y)==2) { ... }
    

    将在第一次无法匹配两个值时退出循环,原因可能是文件结束或文件结束( 返回EOF(即-1)或输入匹配错误(如 xyzzy 42 %d %d 所以 扫描 不给任何人写信 x y )当它返回小于2的值时。

    当然, 扫描 你的朋友在分析正常人的真实输入时。它在处理错误案例时有许多缺陷。

    编辑: 已更正错误: 扫描 EOF 在文件末尾,或一个非负整数,计算它成功设置的变量数。

    关键是因为任何非零值 TRUE while(scanf(...)) 是无限循环,除非遇到无法根据其格式转换的输入文本。

    我再怎么强调也不为过 fgets sscanf 对于一些简单的解析可能已经足够了,但即使这样,它也很容易被边缘情况和错误所淹没。

        3
  •  3
  •   Windows programmer    14 年前

    您正确理解了C代码。

    有时,测试读取的项目数的原因是有人希望确保所有项目都已读取,而不是scanf在输入与预期类型不匹配时提前退出。在这种特殊情况下,这并不重要。

    通常scanf是一个糟糕的函数选择,因为它不能满足人类用户交互输入的需要。通常,fgets和sscanf的结合会产生更好的结果。在这种特殊情况下,这并不重要。

    另一方面,您的替代代码并不完全是替代代码。如果scanf返回-1,那么while循环将执行。

        4
  •  1
  •   abelenky    14 年前

    首先,通过与1比较,它变成一个显式布尔值(true或false)。如果不进行比较,您将在一个整数上进行测试,该整数在C中有效,但在以后的语言(如C#)中无效。

    第二,有些人会用while([function])而不是while([return value])来阅读第二个版本,并且在测试一个函数时会暂时感到困惑,因为很明显,测试的意思是测试返回值。

    这完全是个人喜好的问题,就我而言,两者都是有效的。

        5
  •  1
  •   AnT stands with Russia    14 年前

    isdigit() 例如,打电话)。其他一切都应该使用显式比较。在这种情况下(由于 scanf )语义是非布尔的,所以显式比较是有序的。

    此外,通常可以省略的比较通常是与 1 在这种情况下)最好三思而后行,确保您知道自己在做什么(再次查看JRL的答案)。

    在任何情况下,当比较可以安全地省略并且您实际省略它时,条件的实际语义保持不变。如果这是您所担心的,那么它对结果代码的效率绝对没有影响。