C scanf() 函数,如何在 EOF/EOT 处终止?

标签 c scanf

我编写了一个简单的程序来测试 C 语言中的 scanf() 函数。它基本上从终端读取,char通过char转载return valuechar读;如果满足 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 sectionC11 Standard - 7.21.6.2 The fscanf function(p16)

关于C scanf() 函数,如何在 EOF/EOT 处终止?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60843089/

相关文章:

c - 如何打印 uint8_t 字节数组?

c - 如何初始化、创建矩阵,然后使用结构进行打印

C sscanf 和字符串格式

c - 列表实现中出现不清楚的错误

c++ - 管道以提供文件作为 C 程序的输入

c - Valgrind 提示调用 fgets

c - Linux 交叉编译库

c - 为什么 scanf() 不接受我的第二个输入?

c - 纠结于如何从用户定义值的数组中获取索引的值

编译器不会在 scanf() 处停止输入