【问题标题】:Why is this a valid scanf statement to break out of a while loop?为什么这是跳出 while 循环的有效 scanf 语句?
【发布时间】:2020-08-15 05:34:32
【问题描述】:

为什么这是跳出无限 while 循环的有效代码行?

if (scanf("%s", word) != 1) break;

【问题讨论】:

  • scanf 返回什么?

标签: c if-statement while-loop scanf


【解决方案1】:
if (scanf("%s", word) != 1) break;

scanf 返回成功消费的项目数。该值用作表达式内的左侧操作数。因此,这个表达式是完全有效的。

在下面的示例中,如果没有发生 I/O 错误并且字符串转换成功,则该值应为 1,因为只有一个项目可以使用。

我猜这个if 语句是一个循环的一部分,其目的是从输入中读取后续单词,直到遇到stdinEOF 状态或用作输入的任何重定向文件,因为条件只有这样如果发生EOF 或另一个I/O 错误,则评估为true(并以此打破周围的循环),因为scanf() 在这种情况下返回0

这将使您了解如何评估和解释此 if 语句。

【讨论】:

  • EOF 是带外发生的事情。 IOW你在流中没有遇到EOF,流可以进入EOF状态或者其他错误状态
  • @M.M 现在好点了吗?我从来没有认真地想过这个问题。我的想法是FILEEOF 直接插入到流中。好吧,我必须阅读更多内容。也谢谢你。
【解决方案2】:

上面提到的 break 语句及其保护是有效的,但它在撒谎。考虑循环

while (1) {
   ...
}

根据结构化编程的规则,循环不应该退出,除非程序退出。而不是使用 break 语句,一个结构正确的程序应该使用函数 scan 的返回值作为循环保护,如下所示:

tokenCount = scanf("%s", word);
while (tokenCount == 1) {
    ...
    tokenCount = scanf("%s", word);
}

如果表达式没有副作用,也更容易推断程序的正确性;这就是为什么返回值存储在一个变量中(具有有意义的名称)。

【讨论】:

  • 有些人(包括我自己)更喜欢带有break 语句的无限循环,而不是带有显式结束条件的“正确”循环。这使得在开发的早期阶段更容易移动代码。此外,如果您必须在循环外重复部分代码以避免无限循环,那就特别难看。
  • 您的建议更糟,因为重复了两次相同的代码。 en.wikipedia.org/wiki/Don%27t_repeat_yourself
  • @M.M 这是一个有效的观点。但是,在我看来,收益大于成本。扫描语句并不复杂。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-06-16
  • 1970-01-01
  • 2010-12-31
  • 1970-01-01
  • 1970-01-01
  • 2015-04-08
  • 1970-01-01
相关资源
最近更新 更多