2011-09-10 102 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控制檯會忽略它,並且不會將字符傳遞給正在運行的程序。我不知道爲什麼會發生這種情況。 –

相關問題