2009-07-08 53 views
1

在VS 2005,我有一些代碼,看起來像這樣:ifstream seekg超越最終不會在VS 2008 Express中返回eof?

ifs.open("foo"); 
while (!ifs.eof()) 
{ 
    ifs.read(&bar,sizeof(bar)); 
    loc = ifs.tellg(); 
    loc += bar.dwHeaderSize; 
    // four byte boundary padding 
    if ((loc % 4) != 0) 
     loc += 4 - (loc % 4); 
    ifs.seekg(loc,ios::beg); 
} 
ifs.close(); 

的代碼在VS 2005中工作得很好,但在VS 2008中快速失敗。從我所知道的來看,VS 2008在代碼追尋到文件末尾後沒有返回eof()。我錯過了什麼嗎?我通過添加一個明確的檢查來確定它是否超出了文件大小,但我想確保我理解ifstream是否正確。

回答

2

EOF標誌僅在您嘗試讀取文件末尾後觸發。
正在讀取upto文件結尾不會觸發它。

這就是爲什麼大多數的代碼如下所示:

while(ifs.read(&bar,sizeof(bar))) 
{ 
    // Do Stuff 
} 

如果read()方法的結果去高達的EOF循環將被輸入。
如果read()方法的結果去過去的EOF循環將不enetered

  • 注意:閱讀()將只走過去的EOF如果有留下的文件中的零個字節。否則它會讀到文件的末尾。因此,如果文件中還剩下一些東西,則始終輸入循環。

原因是讀取結果(返回值)是對流的引用。如果流在布爾上下文中使用(如if測試表達式),它將被轉換爲可以在這種上下文中使用的類型。此轉換的結果測試EOF標誌(除了其他幾個標誌之外),並在EOF爲真時返回false的對等值。

注:
此技術更好地工作,如果你使用操作符重載< <您的酒吧類,因爲這應該閱讀正是它需要的對象,而不要去過去的EOF。然後讓對象直接讀取到文件末尾,而不必重新開始。我擔心讀取的事情是,如果read()需要10個字節並且文件中只有5個字節,那麼部分填充的對象會發生什麼?

如果你想繼續使用你的風格的代碼應該是這樣的:

ifs.open("foo"); 
while (!ifs.eof()) 
{ 
    ifs.read(&bar,sizeof(bar)); 
    if (ifs.eof()) 
    { break; 
    } 
    // Do Stuff 
}