为什么我的 scanf while 循环在使用换行符时不退出?
Why does my scanf while loop not exit when consuming newline characters?
// 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 循环退出。
Why is this happening?
循环没有退出,因为它正在等待更多输入。
你可以
发送一对 \n\n
所以 scanf("%[^\n]...
returns 0 因为它无法扫描第二个 \n
或
关闭stdin
(以特定实现方式)所以scanf()
returnEOF
,一个负数。
最好使用 fgets()
。 虽然还不清楚你希望循环在什么条件下结束(除了 stdin
闭包)。
while (fgets(someCharArray, sizeof someCharArray, stdin)) {
// Lop off potential trailing \n if desired
someCharArray[strcspn(someCharArray, "\n")] = '[=10=]';
printf("%s\n", someCharArray);
}
注意:scanf("%[^\n]s", someCharArray)
中的 "s"
没有任何作用 - 删除它。此外,这种没有宽度的格式不会限制扫描到 someCharArray
的最大字符数,不应在质量代码中使用。
I would expect the consuming of the newline character will prepare the outer scanf to scan the next filename, which is what it seems to be doing.
是的 - 没错。较早的 scanf("%[^\n]...
对扫描的字符数没有限制,这可能会导致未定义的行为 (UB),那么为什么要期望其余代码的行为呢?
But after the final filename is scanned, I expect the nested scanf to not scan anything.
如果最终文件名后面有 '\n'
,scanf("%*c");
将使用它。如果最终文件名缺少任何后续字符,scanf("%*c");
将耐心等待一个字符。如果输入流已经关闭,它将return EOF
而不是等待。代码没有 report/test scanf("%*c");
的结果,所以我们只能猜测。
Then the outer scanf to not scan anything either. And the while loop exits.
正确,如果要扫描的第一个字符是 '\n'
,它将保留在 stdin
中,而 scanf()
将 return 0。如果 stdin
关闭时,scanf()
将 return 负数 EOF
.
// 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 循环退出。
Why is this happening?
循环没有退出,因为它正在等待更多输入。
你可以
发送一对
\n\n
所以scanf("%[^\n]...
returns 0 因为它无法扫描第二个\n
或关闭
stdin
(以特定实现方式)所以scanf()
returnEOF
,一个负数。
最好使用 fgets()
。 stdin
闭包)。
while (fgets(someCharArray, sizeof someCharArray, stdin)) {
// Lop off potential trailing \n if desired
someCharArray[strcspn(someCharArray, "\n")] = '[=10=]';
printf("%s\n", someCharArray);
}
注意:scanf("%[^\n]s", someCharArray)
中的 "s"
没有任何作用 - 删除它。此外,这种没有宽度的格式不会限制扫描到 someCharArray
的最大字符数,不应在质量代码中使用。
I would expect the consuming of the newline character will prepare the outer scanf to scan the next filename, which is what it seems to be doing.
是的 - 没错。较早的 scanf("%[^\n]...
对扫描的字符数没有限制,这可能会导致未定义的行为 (UB),那么为什么要期望其余代码的行为呢?
But after the final filename is scanned, I expect the nested scanf to not scan anything.
如果最终文件名后面有 '\n'
,scanf("%*c");
将使用它。如果最终文件名缺少任何后续字符,scanf("%*c");
将耐心等待一个字符。如果输入流已经关闭,它将return EOF
而不是等待。代码没有 report/test scanf("%*c");
的结果,所以我们只能猜测。
Then the outer scanf to not scan anything either. And the while loop exits.
正确,如果要扫描的第一个字符是 '\n'
,它将保留在 stdin
中,而 scanf()
将 return 0。如果 stdin
关闭时,scanf()
将 return 负数 EOF
.