2016-09-04 28 views
0

我寫了一個小程序,以測試從stdin閱讀文本文件:閱讀文本文件停止在最後一行

int main(){ 
    char c; 

    while(!feof(stdin)){ 

     c = getchar();  //on last iteration, this returns '\n' 

     if(!isspace(c))  //so this is false 
      putchar(c); 

     //remove spaces 
     while (!feof(stdin) && isspace(c)){ //and this is true 
       c = getchar(); //  <-- stops here after last \n 
       if(!isspace(c)){ 
        ungetc(c, stdin); 
        putchar('\n'); 
       } 
     } 
    } 
    return 0; 
} 

我再傳給它的小文本文件:

jimmy 8 
phil 6 
joey 7 

與最後一行(joey 7)以\n字符結尾。

我的問題是,它讀取和打印最後一行後,循環回來檢查更多的輸入,沒有更多的字符要讀取,它只停在代碼塊中記錄的行。

問題:feof()返回true的唯一方法是讀取失敗後,如下所示:Detecting EOF in C。爲什麼不是最終致電getchar觸發EOF,我怎樣才能更好地處理這個事件?

+4

[爲什麼「 while(!feof(file))「總是錯?](http://stackoverflow.com/q/5431941/1679849) –

+0

我不確定。它沒有檢測到任何失敗的讀取? – corporateWhore

+4

請點擊鏈接並閱讀。你應該從'getchar()'(它返回一個'int',而不是'char')的返回值,並且對EOF進行測試。作爲'while()'語句的條件測試'feof()'幾乎總是錯誤的。 –

回答

2

有你的代碼中的多個問題:

  • 你不包括<stdio.h>,也不<ctype.h>,或者至少你沒有張貼整個源代碼。使用feof()檢查文件結尾。這幾乎從來都不是正確的方法,如Why is 「while (!feof (file))」 always wrong?
  • 中強調的那樣您從流中讀取char變量中的字節。這可以防止EOF的正確測試,並且還會導致isspace(c)的未定義行爲。將類型更改爲int

這裏是一個改進版本:

#include <stdio.h> 

int main(void) { 
    int c; 

    while ((c = getchar()) != EOF) { 
     if (!isspace(c)) { 
      putchar(c); 
     } else { 
      //remove spaces 
      while ((c = getchar()) != EOF && isspace(c)) { 
       continue; // just ignore extra spaces 
      } 
      putchar('\n'); 
      if (c == EOF) 
       break; 
      ungetc(c, stdin); 
     } 
    } 
    return 0; 
} 

雖然與ungetc()你的方法在功能上是正確的,這將是最好使用一個輔助變量是這樣的:

#include <stdio.h> 
#include <ctype.h> 

int main(void) { 
    int c, last; 

    for (last = '\n'; ((c = getchar()) != EOF; last = c) { 
     if (!isspace(c)) { 
      putchar(c); 
     } else 
     if (!isspace(last)) 
      putchar('\n'); 
     } 
    } 
    return 0; 
} 
+0

我閱讀了鏈接,並認爲我更瞭解該主題。所以謝謝。但是,即使在合併你的建議更改後,仍然會在最後的'getchar()'調用中停止執行。在第11行。 – corporateWhore

+0

你的意思是*它停止*?它應該至少輸出''\ n'' – chqrlie

+0

好吧,我認爲這是一個eclipse調試器問題。在eclipse中,當調試行進入'while((c = getchar())!= EOF && isspace(c)'時,它會停下來並且不會繼續進行下去,唯一的選擇是按下停止按鈕。當我編譯它並在終端中運行它時,它工作得很好。對於那個很抱歉。 – corporateWhore