How to end scanf by entering only one EOF

这一生的挚爱 提交于 2019-12-02 06:23:23

Edit: it's bug 1190 on glibc, it was apparently done purposefully for System V compatibility (and Solaris behaves in the same way, FreeBSD and NetBSD behave as expected).

Note that your expectation is only partly right.

The CTRL-D key is not an EOF marker in Unix. It flushes the input buffer so that the program can read it. What is considered as an EOF under Unix is a read which returns no character, so if you flush the input buffer at the start of a line, it is considered as EOF. If you flush it after having input some data which has not been flushed (the end of line flush input automatically), you need to flush twice to have a read which returns no character and will be considered as EOF.

Now if I execute this program:

#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;
}

and that I press CTRL-D at the start of a line, I get the behavior I expect:

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

If I don't finish the line but press CTRL-D twice (as I explained above, I expect to press it twice) after foo, I've to press another CTRL-D:

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

and I think this is a bug, the scanf should have exited immediately with a EOF result if entered while feof is 1.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!