2011-12-15 105 views
5

這是我在Stack Overflow上的第一篇文章,所以我希望我不要踩在任何人的腳趾上。K&R:第6章 - 爲什麼getword()函數不讀取EOF?

當然,所有的輸入都是受歡迎和讚賞的,但那些最適合回答的人實際上已經閱讀了這本書,其中第二版的編程語言爲

我剛剛完成了練習6-4的編碼,但我似乎無法弄清楚什麼。爲什麼getword()函數沒有讀取EOF,直到我按下Ctrl + D(我在Arch Linux VM中的C代碼)?

我以前的許多練習都需要從stdin中讀取。我會做的一種方式是通過類似於

while ((c = getchar()) != EOF) {...} 

在這種情況下,我從來不必按Ctrl + D。我輸入我的輸入內容,按Enter鍵,stdin緩衝區被刷新,並自動檢測到EOF。 getword()函數也在其基礎上依賴於getchar(),所以它爲什麼會掛起我的程序?

屏幕取詞()函數被稱爲主():

while (getword(word, MAX_WORD) != EOF) { 
    if (isalpha(word[0])) { 
     root = addtree(root, word); 
    } 
} 

屏幕取詞()函數本身:

int getword(char *word, int lim) { 

    char *w = word; 
    int c; 

    while (isspace(c = getch())) { 
    } 
    if (c != EOF) { 
     *w++ = c; 
    } 
    // This point is reached 
    if (!isalpha(c)) { 
     // This point is never reached before Ctrl+D 
     *w = '\0'; 
     return c; 
    } 
    for (; --lim > 0; w++) { 
     if (!isalnum(*w = getch())) { 
      ungetch(*w); 
      break; 
     } 
    } 
    *w = '\0'; 
    return word[0]; 
} 

我把話來表明,我確定EOF是點不被閱讀。

的函數getch()和ungetch()函數是從第4章中的波蘭表示法計算器所使用的相同的那些(和該程序能夠自動讀取EOF - 通過按回車):

#define BUF_SIZE 100 

char buf[BUF_SIZE]; 
int bufp = 0; 

int getch(void) { 

    return (bufp > 0) ? buf[--bufp] : getchar(); 
} 

void ungetch(int c) { 

    if (bufp >= BUF_SIZE) { 
     printf("ungetch: too many characters\n"); 
    } 
    else { 
     buf[bufp++] = c; 
    } 
} 

因此很遠,這是自本書開始以來我寫的第一個程序,它要求我通過Ctrl + D手動輸入EOF。我似乎無法弄清楚爲什麼。提前說明

大部分升值......

+0

要格式化代碼,請突出顯示它,然後單擊「{}」圖標。這會使突出顯示的區域縮進4個空格,這就是「降價」表示源代碼的方式。另請參閱[編輯幫助頁面](http://stackoverflow.com/editing-help)。我已經爲你修好了。歡迎來到Stackoverflow! – 2011-12-15 02:49:19

回答

3

不得不鍵入Ctrl + D來獲取EOF是Unix類系統的正常行爲。

爲您的代碼片段:

while ((c = getchar()) != EOF) {...} 

輸入絕對不應終止循環(除非你的tty設置是一團糟。)。

嘗試編譯並運行此程序:

#include <stdio.h> 
int main(void) 
{ 
    int c; 
    while ((c = getchar()) != EOF) { 
     putchar(c); 
    } 
    return 0; 
} 

應該打印您所輸入的一切,當你在一行的開頭鍵入控制d只應終止(或當你與控制殺死它-C)。

+0

或者當你連續輸入兩個control-D時。或者當你用'退出'信號殺死它時。 :D – 2011-12-15 07:47:20

2

,如果你不喜歡的東西類型輸入標點符號的「沒有達到」點只能達到 - 或者你讀EOF。如果你輸入一個字母或空格,那麼它被繞過。

當輸入從,則沒有檢測到EOF的終端(標準輸入),直到在鍵入控制-d(或任何在stty -a輸出指定)你打另一個之後輸入一個新行,或之後到來Control-D(如此連續兩個)。代碼通過換行符讀取,因爲換行符'\n'滿足isspace()

+0

您也是正確的,先生,輸入非字母表將達到我指出的在Control-D之前永遠不會達到的點。我只在詞樹的背景下思考單詞。 – 2011-12-16 02:15:20

0

我對以前的程序感到困惑的原因是我以前的程序的效果總是打印在的標準輸出的while循環中,所以我總是立即看到結果,無需輸入EOF 。對於這個,直到while循環結束後纔會打印該樹,所以需要EOF相遇。我沒有意識到這一點,這就是爲什麼我瘋了。

再次感謝您設置我直!