【发布时间】:2021-10-12 17:12:52
【问题描述】:
我之前正在测试一些看起来像这样的代码:
char input;
int data;
while(scanf("%c %d", &input, &data) != EOF) {
puts("foo");
}
当我使用以下输入阅读它时:
c 8
c 10
c 15
c 18
^D
这是我的输出:
foo
foo
foo
foo
foo
foo
foo
foo
虽然我只希望foo 打印一次;也就是说,一旦发送了 EOF 信号。我还尝试在我的 IDE 之外并在终端中手动运行它(因为 CLion 存在 EOF 问题),当我通过终端手动运行它时, foo 将在第一次输入后打印一次,然后每次都打印两次。
但是,当我在循环中使用 printf 而不是 puts 时,我的代码会按预期运行。我想知道为什么 puts 在这里造成了问题?我想这与 IO 流有关,但我不确定为什么会发生这种情况。
这是未定义的行为吗?如果是这样,为什么会这样?
编辑:cmets 中有人说他们没有遇到同样的问题。我附上了我的代码+终端的屏幕截图。 如果这有什么不同,我也在运行 gcc-9.4。
【问题讨论】:
-
我无法重现这种行为——
printf对我来说与puts的行为相同。我看不出为什么它应该这样做;也许不相关的东西出了问题? -
请提供minimal reproducible example 来证明您的观察。
-
我会写
while(scanf(" %c%d", &input, &data) == 2)注意空格字符位置的变化。了解scanf如何使用不同的格式说明符(在输入中的格式字符串 和 中)处理空格以及它返回什么是很重要的。 -
没有“EOF 信号”。当输入流关闭时,scanf 返回一个整数值(几乎可以肯定是 -1),它由令牌 EOF 表示给 C 预处理器,并在文档中称为“EOF”。这不是任何形式的信号。它只是当它正在读取的文件没有更多数据时scanf返回的整数值。
-
scanf规则一:成功的返回值是成功转换的输入数。所以检查一下(在本例中为 2)——不要只检查 1/0/EOF。scanf规则 2:%c略有不同。要么不要全部使用它,要么总是在它前面加一个空格:" %c %d"。如果您真的知道自己在做什么,请仅使用不带空格的%c(尽管在这种情况下,您不妨只使用getchar)。
标签: c