【问题标题】:How to end scanf by entering only one EOF如何通过仅输入一个 EOF 来结束 scanf
【发布时间】:2013-11-10 11:43:24
【问题描述】:

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

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

【问题讨论】:

  • while (! feof (stdin)) 替换为while (1)。 (feof() 总是 错误...)另外:EOF 不是 字符;您不能像将字符发送到流或文件一样发送它。
  • 如果 stdin 是您的终端,则没有 EOF 条件。如果文件不是具有有限数据的真实文件,而是可以随时生成更多数据的键盘(真实或虚拟),则很难到达文件末尾。
  • 我将它替换为while(1) 并添加了if (status==EOF) break; 结果是我现在必须按三下Ctrl+D
  • 我这辈子从没见过这么奇怪的代码格式。你从哪里学来的?

标签: c stdin scanf eof feof


【解决方案1】:

编辑: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 结果。

【讨论】:

    猜你喜欢
    • 2012-05-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-12
    • 1970-01-01
    相关资源
    最近更新 更多