2015-09-18 58 views
7

,因爲它似乎對我更具可讀性和強大的我總是用這種方法檢查EOF和fgetc()的錯誤的更好方法是什麼?

int c; 
while ((c = fgetc(fp))!=EOF) 
{ 
    printf("%c", c); 
} 

。但礦link的答案,chux評論說

如果(FEOF(FP))比 詮釋三更穩健;而((C =龜etc(FP))!= EOF)

作爲

while(1) 
    { 
     c = fgetc(fp); 
     if (feof(fp)) 
     { 
      break ; 
     } 
     printf("%c", c); 
    } 

比第一版本更堅固。那麼我應該使用哪個版本?請解釋爲什麼該版本更好。

編輯

問題Why is 「while (!feof (file))」 always wrong?有問爲什麼FEOF()在控制迴路總是錯的。但如果以適當的方式檢查feof()是否總是錯誤?解釋是可觀的。

+4

使用第一個版本。第二個不是「更強大」,但它需要更多的編碼。它也無法檢查錯誤情況。 – fuz

+0

@user - 不,正確的C++方式是while(cin >> c)',而絕對不是**'while(!cin.eof())'。請參閱[爲什麼iostream :: eof內部循環條件被認爲是錯誤的](http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-considered-wrong) –

+4

@Kninnug It並不是該問題的重複。 – ashiquzzaman33

回答

4

我一般程序的輸入循環是這樣的:

int c; 

while ((c = fgetc(fp)) != EOF) { 
    /* do something with c here */ 
} 

/* check if EOF came from an end-of-file or an error */ 
if (ferror(fp)) { 
    /* error handling here */ 
} 

一般情況下不應使用這樣的循環狀態:

while (!feof(fp)) { 
    /* do stuff */ 
} 

for (;;) { 
    c = fgetc(fp); 
    if (feof(fp)) 
     break; 
} 

因爲這打破了當遇到IO錯誤。在這種情況下,fgetc返回EOF,但未設置文件結束標誌。您的代碼可能會進入無限循環,因爲通常會一直存在錯誤情況,直到執行外部操作。

正確的方法是檢查fgetc()的結果:如果它等於EOF,通常可能會停止以IO錯誤和文件結束條件的方式讀取更多數據,但通常不可能閱讀更多數據。然後您應該檢查是否發生了錯誤並採取適當的措施。

+7

OP要求*說明*。 –

+1

這不是一個無用的答案(它應該被低估),但並不真正回答OP的期望。 – edmz

+0

@KolyolyHorvath滿意嗎? – fuz

1

建議的改進不會更好,即使不夠健壯。

如解釋here所示,如果發生讀取錯誤(無eof),它將進入無限循環。在這種情況下,feof將返回0,而fgetc返回EOF

您的版本沒有此問題。

此外,您的版本更短,更簡單和非常標準。

+0

@Ashiquzzaman:這不是重複的。 –

4

測試錯誤條件的問題C.想出了因爲一個corner case

fgetc()返回int。它的值在unsigned charEOF的範圍內(一些負數)。

int ch; 
while ((ch = fgetc(fp)) != EOF) { 
    // do something with ch 
} 
if (ferror(fp)) Handle_InputError(); 
if (feof(fp)) Handle_EndOffFile(); // Usually nothing special 

然而C允許unsigned char具有較寬的範圍比int的正數。將unsigned char轉換爲int具有實施定義的行爲,這可能導致unsigned char值被轉換爲負值int - 並且匹配EOF

這樣的平臺很少見,不在2015年的主流。大多數將有UCHAR_MAX <= INT_MAX和上述風格是典型的使用。令人懷疑的是這些平臺將會變得很普遍,這是由於代碼的數量,如上所述,依賴於EOF不同於unsigned char轉換爲int

應該在代碼需要處理罕見的情況下UCHAR_MAX > INT_MAX,然後

int c; 
for (;;) 
{ 
    c = fgetc(file); 
    if (c == EOF) { 
     if (feof(file)) break; 
     if (ferror(file)) break; 
     // fall through if both if's fail. 
    } 
    // do stuff with c 
} 

while (!feof (file)) always wrong?亮點的錯誤代碼往往使得在使用fgetc(in)結果檢查問題之前流行的參考。上述兩個代碼在使用fgetc()的結果之前檢查錯誤情況。


第二個代碼處理所有情況,包括可能只適用於坐在一個長久被遺忘的垃圾堆中的計算機的情況。第一個更常見。

相關問題