【问题标题】:In linux ctrl + d(EOF) behavior in three different situation在linux ctrl + d(EOF) 三种不同情况下的行为
【发布时间】:2020-09-03 14:15:23
【问题描述】:
//first example
void readInWBW()
{
    int ch; 
    while((ch=getchar()) != EOF)
        putchar(ch);
}

当我输入“qweCTRL+D”时,第一次输入 ctrl+z 的地方只是刷新缓冲区,然后我重新输入 "ctrl+d" 所以它就像 "qweCTRL+DCTRL+D",然后 EOF 工作,程序终止。 结果是

$ ./a.out
qweqwe$

//second example
void guess()
{
    int guess = 1;  
    printf("Pick an integer from 1 to 100. I will try to guess ");
    printf("it.\nRespond with a y if my guess is right and with");
    printf("\nan n if it is wrong.\n");
    printf("Uh...is your number %d?\n", guess);
    while (getchar() != 'y'){      //<---------------------------
        printf("Well, then, is it %d?\n", ++guess); //<----------
        sleep(1);
    }
    printf("I knew I could do it!\n");
}

在这个例子中,我输入“qweCTRL+D”,它会显示 3 次“Well, then...”,但是如果我再次输入 CTRL+D,程序将进入无限循环。 结果是:

Pick an integer from 1 to 100. I will try to guess it.
Respond with a y if my guess is right and with
an n if it is wrong.
Uh...is your number 1?
qweWell, then, is it 2? //<--------------------------
Well, then, is it 3?
Well, then, is it 4?
Well, then, is it 5?
Well, then, is it 6?
Well, then, is it 7?
Well, then, is it 8?
Well, then, is it 9?
Well, then, is it 10?
Well, then, is it 11?
^C

//third example    
void test()
{
    char ch;
    while((ch = getchar()) != '#')
        putchar(ch); 
}

我尝试像其他示例一样输入“qweCTRL+D”,但是在刷新缓冲区后,“CTRL+D”不再响应,即使我输入“#”,它仍然没有终止。 结果是:

$ ./a.out
qweqwe
#
#
^C
$

我不明白为什么在 example2 和 example3 中有无限循环并且无法终止程序。谁能解释一下,谢谢。

【问题讨论】:

  • 第二个和第三个例子不检查 EOF。

标签: c linux io eof


【解决方案1】:

让我们专注于您的第三个示例。

void test()
{
    char ch;
    while((ch = getchar()) != '#')
        putchar(ch); 
}

请记住,输入 C-d 表示“文件结束”,因此程序停止响应输入是很自然的。你说过没有更多的输入。这就是 EOF 的意思。

所以当你输入 C-d 后,会发生ch = getchar() 会不断读取 EOF。无论您在 C-d 之后键入什么,都不会进入输入流。因此,为什么要进入无限循环的简单答案是 EOF != '#'getchar() 在读取一次后总是会读取 EOF 的事实相结合。

这里可能要提到的另一件事是您正在使用缓冲输入。所以getchar() 只会等到stdin 中有东西。当您输入几个字符时,它们不会被刷新到stdin,直到您按回车或 C-d。

另外,请记住 EOF 不适合 char。函数getchar 返回一个int,它是一个适合charEOF 的数字。变量 ch 应声明为 int 并正确检查 EOF

可以重置stdin,尽管我不确定是否可以通过便携式方式进行。但这里有个问题:How to restart stdin after Ctrl+D?

【讨论】:

  • 谢谢,很有帮助,我尝试在第三个“while((ch = getchar()) != '#') putchar(ch);”之后插入 printf("1")例如,它也会像您解释的那样进入无限循环。
猜你喜欢
  • 2017-05-04
  • 2013-11-09
  • 2015-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-17
  • 1970-01-01
相关资源
最近更新 更多