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

car*_*995 7 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;
}
Run Code Online (Sandbox Code Playgroud)

题:

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

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

  3. EOF终止字符输入仅在我^z在一行上指定或通过这样做时才起作用:^zabvcjdjsjsj.为什么会这样?

Bri*_*ach 15

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

你的程序没有实际执行的循环,直至\n或者^z已经被你在一行的末尾输入.终端驱动程序正在缓冲输入,并且在发生之前它尚未发送到您的进程.

在一行结束时,击中^z(或^dLinux上的)不使终端驱动程序发送EOF.它只会将缓冲区刷新到您的进程(没有\n).

在一行开头命中^z(或^d在Linux上)被终端解释为"我想要发出EOF信号".

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

printf("%d\n",ch);
Run Code Online (Sandbox Code Playgroud)

运行你的程序:

$ ./test
abc                      <- type "abc" and hit "enter"
97
98
99
10
abc97                    <- type "abc" and hit "^z"
98
99
Run Code Online (Sandbox Code Playgroud)

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

一种看待这种情况的方法是点击^v然后点击^z作为你的程序的输入.

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


CB *_*ley 5

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