【问题标题】:Why does my scanf while loop not exit when consuming newline characters?为什么我的 scanf while 循环在使用换行符时不退出?
【发布时间】:2016-07-06 10:25:24
【问题描述】:
// Some initialization code

dup2(fd[0], fileno(stdin));

// This process is receiving the output of "ls -1"

while (scanf("%[^\n]s", someCharArray) > 0) {
    scanf("%*c");
    printf("%s\n", someCharArray);
}

这将成功打印所有文件。但是,循环永远不会退出。如果我拿走scanf("%*c"),它会退出,但只打印第一个文件名。

我希望换行符的消耗将使外部scanf 准备扫描下一个文件名,这似乎是在做的。但是在扫描最终文件名之后,我希望嵌套的 scanf 不会扫描任何内容。然后外部scanf 也不扫描任何东西。而while循环退出。

为什么会这样?

【问题讨论】:

  • 转换说明符末尾的 s 不会像您认为的那样。
  • 您可能需要检查例如this scanf (and family) reference.
  • 我原以为只使用fgets 并修剪换行符会更容易。
  • 奇怪的是,这段代码对我有用。我打开了 popen("ls -l", "r"); ,打印完所有文件后循环完成。

标签: c while-loop newline scanf


【解决方案1】:

循环不会退出,因为它正在等待更多输入。

你可以

  1. 发送一对\n\n,所以scanf("%[^\n]...返回0,因为它无法扫描第二个\n,或者

  2. 关闭stdin(以特定于实现的方式)所以scanf()返回EOF,一个负数。

最好使用fgets()@WhozCraig 虽然目前还不清楚您希望循环在什么条件下结束(stdin 关闭除外)。

while (fgets(someCharArray, sizeof someCharArray, stdin)) {
  // Lop off potential trailing \n if desired
  someCharArray[strcspn(someCharArray, "\n")] = '\0';

  printf("%s\n", someCharArray);
}

注意:scanf("%[^\n]s", someCharArray) 中的 "s" 没有任何作用 - 删除它。此外,这种没有宽度的格式不会限制扫描到someCharArray 的最大字符数,并且不应在质量代码中使用。


我希望换行符的消耗将使外部 scanf 准备扫描下一个文件名,这似乎是在做的。

是的——没错。较早的scanf("%[^\n]... 对扫描的字符数没有限制,这可能导致未定义的行为 (UB),那么为什么要期望其余代码能够正常运行呢?

但是在扫描最终文件名之后,我希望嵌套的 scanf 不会扫描任何内容。

如果最终的最终文件名后面有一个'\n'scanf("%*c"); 将使用它。如果最终文件名缺少任何后续字符,scanf("%*c"); 将耐心等待一个字符。如果输入流已经关闭,它将返回EOF 而不是等待。代码不会报告/测试scanf("%*c"); 的结果,所以我们只能猜测。

然后外部 scanf 也不扫描任何东西。而while循环退出。

是的,如果要扫描的第一个字符是 '\n',它将保留在 stdin 中,scanf() 将返回 0。如果 stdin 关闭,scanf() 将返回负数 EOF .

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-03
    • 1970-01-01
    • 2019-05-10
    • 2013-08-04
    相关资源
    最近更新 更多