1

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

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

1 回答 1

4

编辑:它是 glibc 上的错误 1190,显然是为了 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

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

于 2013-11-10T13:09:31.610 回答