Windows命令提示符中的EOF不会终止输入流

时间:2011-09-10 17:30:25

标签: c eof

代码:

#include <stdio.h>
#define NEWLINE '\n'
#define SPACE ' '

int main(void)
{
    int ch;
    int count = 0;

    while((ch = getchar()) != EOF)
    {
        if(ch != NEWLINE  && ch != SPACE)
            count++;
    }
    printf("There are %d characters input\n" , count);

    return 0;
}

问题:

  1. 一切正常,它会忽略空格和换行符并输出输入到屏幕的字符数(在这个程序中我只是将逗号,感叹号,数字或任何可打印的特殊符号字符作为符号作为字符当我点击EOF模拟时^z

  2. 但是当我将这一行输入程序时出现了问题。例如,我输入了这个:abcdefg^z,这意味着我在^z之前和之后输入了一些字符。该程序将继续要求输入,而不是终止程序并打印出总字符。

  3. EOF终止字符输入仅在我在一行中指定^z或通过执行此操作时才有效:^zabvcjdjsjsj。为什么会这样?

2 个答案:

答案 0 :(得分:15)

几乎每个终端驱动程序都是如此。您将使用Linux获得相同的行为。

您的程序实际上并没有执行循环,直到您在一行结束时输入\n^z。终端驱动程序正在缓冲输入,并且在发生之前它尚未发送到您的进程。

在一行结束时,点击^z(或Linux上的^d会导致终端驱动程序发送EOF。它只会使缓冲区刷新到您的进程(没有\n)。

在一行开头点击^z(或Linux上的^d)会被终端解释为“我想发信号EOF”。

如果在循环中添加以下内容,则可以观察到此行为:

printf("%d\n",ch);

运行你的程序:

$ ./test
abc                      <- type "abc" and hit "enter"
97
98
99
10
abc97                    <- type "abc" and hit "^z"
98
99

为了更好地理解这一点,你必须意识到EOF不是一个角色。 ^z是终端本身的用户命令 。因为终端负责接收用户输入并将其传递给进程,所以这变得棘手并因此引起混淆。

通过点击^v然后点击^z作为您计划的输入,可以看到这种情况。

^v是告诉终端的另一个终端命令,“嘿,我输入的下一个东西 - 不要将其解释为终端命令;而是将其传递给进程'输入”。

答案 1 :(得分:5)

^Z只有在一行开头输入时,才会通过控制台将EOF信号转换为程序。这就是Windows控制台的工作方式。我知道这种行为没有“解决方法”。