我编写了一个简单的程序来测试 C 语言中的 scanf() 函数。它基本上从终端读取,char
通过char
,转载return value
和 char
读;如果满足 EOF/EOT 或 \n newline
则终止已读。
#include <stdio.h>
#include <stdbool.h>
int main(void) {
char c; int ret;
printf("Enter the chars to test: ");
//LOOP (scan & print) only when return is not EOF and char is not newline
while ( ((ret = scanf("%c", &c)) != EOF) && c!='\n' ) {
printf("%i %c\n", ret, c);
}
return 0;
}
如果按下换行符 ( Enter
),它会正确终止。但它不会仅仅以一个 Ctrl-D
结束。 。单Ctrl-D
将刷新键入的“字符”并打印它们。然后,它将再次等待输入,尽管 EOF
已与 Ctrl-D
一起发送。如果我们按Ctrl-D
在第一次(2x)之后再次进行第二次,或者只是 Enter
它会终止。所以你将需要两个连续的 Ctrl-D
终止程序(或本例中的循环)。
示例:
如果输入987
在终端上按 ,然后按 Enter
;然后1 9
, 1 8
, 1 7
将打印在每个换行符上。
如果输入987
在终端上按 ,然后按 Ctrl-D
;然后1 9
会打印在同一行(因为输入 Enter
后没有输入987
), 1 8
, 1 7
将打印在换行符上。那么它仍然会等待更多的输入,除非直接输入第二个连续的 Ctrl-D
来终止它。 或换行符 ( Enter
)。所以它(程序)只会在 newline
之后停止(退出循环)或连续第二个Ctrl-D
.
我很困惑。不应该是一个Ctrl-D
发送到此处停止循环?仅收到一个 Ctrl-D
后我应该做什么来停止程序(scanf 循环) ?
我在 Lubuntu 19.10 上使用 gcc 9.2.1 测试了代码。
最佳答案
问题是 scanf()
不会返回 EOF
,直到不再有输入等待并且遇到 EOF
。 (您的"%c"
转换说明符将接受任何字符,包括'\n'
字符,作为有效的,并认为它是成功的转换)
当您键入一行字符时,例如"abcdefg"
并尝试按 Ctrl+d(表示输入结束),输入 ("abcdefg"
) 会被处理并当到达 'g'
时,scanf()
会阻塞等待下一个输入。 (因为转换成功并且没有发生匹配或输入失败)
一旦Ctrl+d被输入第二次(表示输入结束),当没有输入要处理时,在第一次成功之前就到达了EOF
转换并且发生输入失败,scanf()
然后返回 EOF
。
参见:man 3 scanf -- RETURN VALUE section和 C11 Standard - 7.21.6.2 The fscanf function(p16)
关于C scanf() 函数,如何在 EOF/EOT 处终止?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60843089/