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

问题描述 投票:1回答:1

我编写了一个简单的程序来测试C中的scanf()函数。它基本上是从终端读取char并通过char进行读取,reprinting 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,但它将再次等待输入。如果我们在第一个(2x)之后第二次再次按Ctrl-D或仅按Enter,它将终止。因此,您将需要两个连续的Ctrl-D来终止程序(在这种情况下为循环)。

示例:

如果在终端上输入987,则按Enter;然后1 91 81 7将分别打印在换行符上。

如果在终端上输入987,则按Ctrl-D;然后1 9将打印在同一行上(因为在输入Enter输入后没有键入987),1 81 7 将打印在换行符上。然后,它将继续等待更多输入,除非通过直接输入第二个连续的[[Ctrl-D或使用换行符(Enter)终止它。因此,它(程序)将仅在newline或2个连续的Ctrl-D之后停止(退出循环)。

我很困惑。发送的单个Ctrl-D是否不应该在此处停止循环?仅收到一个Ctrl-D后,我应该怎么做才能停止程序(scanf循环)?

我用gcc 9.2.1在Lubuntu 19.10上测试了代码。

c scanf
1个回答
0
投票
测试返回值是否为零,而不是EOF。首次达到eof时,返回零。零后的下一个scanf返回EOF

while ( ((ret = scanf("%c", &c)) != 0) && c!='\n' ) { printf("%i %c\n", ret, c); }

如果使用更复杂的输入格式,则可以将if (feof(stdin) != 0) break;添加到循环主体中。

如果仅阅读字符,使用fgetc会更好吗?

© www.soinside.com 2019 - 2024. All rights reserved.