c - 如何只输入一个EOF结束scanf

标签 c stdin scanf eof feof

我遇到了这个问题。我正在使用 while 循环来扫描数字字符串,需要结束扫描并开始执行程序的其余部分。我只是想不通,如何刷新标准输入或做任何不按 Ctrl+D 两次的事情。我只需要发送一次 EOF 来告诉我的循环结束。

while (! feof (stdin))
    {status=scanf ("%d", &array[i]);
    if ( (status != 1 && status != EOF) )
    {       printf("\nWrong input.\n");
            return 1;}
    i++;}

最佳答案

编辑:it's bug 1190 on glibc , 它显然是为了 System V 兼容性而有意完成的(Solaris 的行为方式相同,FreeBSD 和 NetBSD 的行为符合预期)。

请注意,您的期望只是部分正确。

CTRL-D 键在 Unix 中不是 EOF 标记。它刷新输入缓冲区,以便程序可以读取它。在 Unix 下被视为 EOF 的是不返回任何字符的读取,因此如果您在行首刷新输入缓冲区,则它被视为 EOF。如果在输入一些尚未刷新的数据(行尾自动刷新输入)后刷新它,则需要刷新两次才能进行不返回任何字符的读取,并将被视为 EOF。

现在如果我执行这个程序:

#include <stdio.h>

int main()
{
    int status;
    char tab[200];
    while ((status = fscanf(stdin, "%s", tab)) == 1) { 
        printf("Read %s\n", tab); 
        printf("status=%d\n", status);
        printf("ferror=%d\n", ferror(stdin));
        printf("feof=%d\n", feof(stdin));
    }
    printf("\nOut of loop\nstatus=%d\n", status);
    printf("ferror=%d\n", ferror(stdin));
    printf("feof=%d\n", feof(stdin));
    return 0;
}

并且我在一行的开头按 CTRL-D,我得到了我期望的行为:

foo
Read foo
status=1
ferror=0
feof=0
^D
Out of loop
status=-1
ferror=0
feof=1

如果我没有完成该行但在 foo 之后按了两次 CTRL-D(正如我上面解释的那样,我希望按两次),我必须再按一次 CTRL-D:

./a.out
foo^D^DRead foo
status=1
ferror=0
feof=1
^D
Out of loop
status=-1
ferror=0
feof=1

我认为这是一个错误,如果在 feof 为 1 时输入 scanf 应该立即退出并返回 EOF 结果。

关于c - 如何只输入一个EOF结束scanf,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19889296/

相关文章:

c - 扫描文件和计算 c 中的值时出现段错误

c - scanf忽略用户输入——保存不相关的数字

c - For循环在C中崩溃

c - C 中的所有数组长度方法都不起作用

docker - 使用 Golang docker SDK - Interactive Container 接受用户输入 os.stdin 到容器

c - "thread storage duration"和 "thread local storage duration"是同义词吗?

python sys.stdin.read() 来自 tail -f

stdin - 是否可以在阻塞模式下运行 sbatch?

c - 当我在没有免费的情况下用新指针分配指针时,这是不好的做法吗?

c - 如何解决 malloc() 损坏指针的情况?