2013-08-30 330 views
2

我正在閱讀一個文本文件,使用while(!feof)循環迭代, 迭代,但是每當我使用這個條件時循環會迭代一個額外的時間。優雅的方式來確定EOF?

我解決了這個問題,這個「修修補補」代碼

while (stop == FALSE) 
{ 
... 

     terminator = fgetc(input); 
     if (terminator == EOF) 
      stop = TRUE; 
     else 
      fseek(input, -1, SEEK_CUR); 
} 

但它看起來和感覺非常糟糕。

+2

可能的重複[爲什麼iostream :: eof裏面的循環條件被認爲是錯誤的?](http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-錯誤) – 2013-08-30 14:15:13

+2

可能是第20個關於CIO在過去幾天中的問題,可能我們需要一個關於該社區維基頁面的文章 – jev

+0

@ H2CO3:從技術上講,這不是iostream問題的重複,因爲這是特別的C,另一個是C++。 –

回答

7

你可以採取的事實,爲分配的值被讀分配得到評估,在這種情況下性格優勢:

while((terminator = fgetc(input))!= EOF) { 
    // ... 
} 
+0

如果'!= EOF'不會讓光標保持前面的字符? – Quaker

+0

@奎克不,爲什麼呢? – 2013-08-30 14:11:42

+0

由於fgetc每次提前指示一個字符,如果終止符!= EOF,那麼終止符將保存相關的字符,並且指示符將在其之前。 – Quaker

6

下面是一個地道的例子(source):

fp = fopen("datafile.txt", "r"); // error check this! 

// this while-statement assigns into c, and then checks against EOF: 

while((c = fgetc(fp)) != EOF) { 
    /* ... */ 
} 

fclose(fp); 
+0

感謝您發佈此信息。在這裏,「feof()」這個問題的熱情非常令人厭倦。 – unwind

+0

@unwind順便說一句,其他答案也不正確嗎? – 2013-08-30 14:12:59

+0

Brian,我正在逐行讀取文本文件,該函數將整行讀入一個字符串。您的解決方案是否會導致修剪後的字符串(缺少該行的第一個字符)? – Quaker

0

同樣你CA讀取行由行:

char buf[MAXLINE]; 
// ... 
while((fgets(buf,MAXLINE,stdin)) != NULL) { 
     do_something(buf); 
} 

由於fgets複製檢測到的換行符,因此可以通過檢查倒數第二個緩衝區元素來檢測 行結束。您可以使用 realloc來調整緩衝區大小(請確保您保留指向緩衝區開始的指針,但將buf+n傳遞到下一個fgets,其中n是讀取字符數)。從關於fgets標準:

從流中讀取字符和將它們存儲爲C字符串到STR直到(NUM-1)的字符已被讀出或達到任一換行或檔案結尾,取其首先發生。換行符使fgets停止讀取,但它被函數視爲有效字符,並且包含在複製到str的字符串中。

或者,您可以使用fread()一次性閱讀整個文件(請參閱鏈接後的示例)。

+0

這不是一個選項,因爲最大線長度是未知的...... – Quaker