如何通过只输入一个EOF结束scanf函数 [英] How to end scanf by entering only one EOF

查看:718
本文介绍了如何通过只输入一个EOF结束scanf函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我encoutering这个问题。我使用whil​​e循环扫描数字串,需要结束扫描并开始着手我的程序的其余部分。我只是想不通,怎么刷新标准输入或做任何事情没有preSS Ctrl + D键两次。我只需要发送EOF只有一次告诉我的循环结束。

 而(!的feof(标准输入))
    {状态= scanf函数(%d个,&安培;阵列[我]);
    如果((状态= 1&安培;!&放大器;状态= EOF)!)
    {printf的(\\ nWrong输入\\ n);
            返回1;}
    我++;}


解决方案

编辑:它的错误在glibc的 1190,这显然是有目的地做了System V的兼容性(和Solaris以同样的方式表现,FreeBSD和NetBSD的像预期的那样)。

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

该CTRL-D键是不是在Unix的一个EOF标记。它刷新输入缓冲区,使程序可以读取它。什么被认为是Unix下一个EOF是读不返回任何字符,所以如果你在一行的开始刷新输入缓冲区,它被认为是EOF。如果你有输入一些数据还没有被刷新(自动刷新行输入结束)后刷新它,你需要冲洗两次,有一个读不返回任何字符,将被视为EOF。

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

 的#include<&stdio.h中GT;诠释的main()
{
    INT状态;
    字符选项卡[200];
    而((状态=的fscanf(标准输入%S,标签))== 1){
        的printf(读%S \\ n,制表符);
        的printf(状态=%d个\\ N,地位);
        的printf(FERROR =%d个\\ N,FERROR(标准输入));
        的printf(=的feof%d个\\ N的feof(标准输入));
    }
    的printf(\\ NOUT循环\\ n状态=%d个\\ N,地位);
    的printf(FERROR =%d个\\ N,FERROR(标准输入));
    的printf(=的feof%d个\\ N的feof(标准输入));
    返回0;
}

和在一行的开始,我preSS CTRL-D,我得到我期望的行为:

 
阅读富
状态= 1
FERROR = 0
的feof = 0
^ D
输出回路
状态= -1
FERROR = 0
的feof = 1

如果我不结束此行,但preSS CTRL-D两次(如我上面所解释的,我希望preSS两次)富之后,我以preSS另一个CTRL- D:

  ./ a.out的
富^ D ^恐惧富
状态= 1
FERROR = 0
的feof = 1
^ D
输出回路
状态= -1
FERROR = 0
的feof = 1

,我认为这是一个错误,在 scanf函数应该如果输入了EOF结果立即退出,而的feof 1

I am encoutering this problem. I am using while loop to scan string of numbers and need to end scanning and start proceeding the rest of my program. I just can't figure out, how to flush the stdin or do anything to not press Ctrl+D twice. I just need to send EOF only once to tell my loop to end.

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

解决方案

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.

这篇关于如何通过只输入一个EOF结束scanf函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆