2011-09-10 70 views
7

代码:EOF在Windows命令提示符不会终止输入流

#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。这是为什么发生?

回答

14

几乎在每个终端驱动程序中都是如此。你会得到使用Linux的相同行为。

您的程序实际上并未执行循环,直到您在行尾输入了\n^z。终端驱动程序正在缓冲输入,并且直到发生这种情况才将它发送到您的进程。

在一个行的末尾,击中(Linux或^d^z确实不原因终端驱动程序发送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^v是另一个终端命令,它告诉终端,“嘿,我输入的下一个东西 - 不会将其解释为终端命令;将它传递给进程的输入”。

4

^Z仅当在行的开头键入时才由控制台转换为程序的EOF信号。这只是Windows控制台的工作方式。对于我所知道的这种行为没有“解决方法”。

+0

然后,为什么^ z不是一个字符,当我把它放在一行中的字符串之后?例如“abcdefg^z”只返回我“输入7个字符”而不是8个字符后输入该行之后的^ z。 – caramel1995

+0

@ caramel23:我相信Windows控制台会忽略它,并且不会将字符传递给正在运行的程序。我不知道为什么会发生这种情况。 –

相关问题