为什么我的scanf while循环在使用换行符时不会退出?

时间:2016-03-19 17:56:04

标签: c while-loop newline scanf

// 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循环退出。

  

为什么会这样?

1 个答案:

答案 0 :(得分:2)

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

你可以

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

  2. 关闭stdin(以具体实施方式),scanf()返回EOF,为负数。

  3. 最好使用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);
    }
    

    注意:"s"中的scanf("%[^\n]s", someCharArray)没有用处 - 放弃它。此格式(没有宽度)也不会将扫描的最大字符数限制为someCharArray,也不应在质量代码中使用。

      

    我希望消费换行符将准备外部scanf来扫描下一个文件名,这就是它似乎正在做的事情。

    是的 - 那是对的。较早的scanf("%[^\n]...对扫描的字符数没有限制,这可能会导致未定义的行为(UB),那么为什么期望其余代码表现出来?

      

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

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

      

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

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