2011-03-29 46 views
2

我有這樣的文字樣本閱讀文本文件中的一行兩次

Ahmed 10 
kmal 5 
doola 6 

,我使用此代碼閱讀

if (myfile.is_open()) 
{ 
    while (myfile.good()) 
{ 

    myfile >> name; 
    myfile >> phone; 
    cout << name <<" "<<phone<<endl; 

} 
myfile.close(); 

}

我得到這個輸出

Ahmed 10 
kmal 5 
doola 6 
doola 6 

此代碼爲何讀取最後一行是兩次?

+0

嘗試'while(myfile.good()&&!myfile.eof())'。 – 2011-03-29 01:32:44

+1

看到如何正確使用流標誌:http://stackoverflow.com/questions/4258887/semantics-of-flags-on-basic-ios – GManNickG 2011-03-29 01:41:46

回答

2

嘗試

while(myfile >> name >> phone) { 
    // your code here 
} 

我相信另一種方法的問題是,除非你真的嘗試閱讀比你應該更多的東西,否則不會發出eof信號。也就是說,當你在上一輪嘗試myfile >> name時。那就失敗了,就像myfile >> phone一樣,只有這樣才能擺脫循環。

+0

這工作正常。 TY – Ahmed 2011-03-29 01:40:42

1

請勿使用while(myfile.good())。它仍然會說true,即使您已經讀取了文件中的最後一行。然後下一個>>將會失敗,從而使namephone變量與最後一個輸入保持不變。改爲:while(myfile >> name >> phone) {...}

+1

同樣的問題.... – Ahmed 2011-03-29 01:34:29

+0

@艾哈邁德:謝,我忘了同樣的問題問題存在'eof()',抱歉。 :)嘗試新版本。 – Xeo 2011-03-29 01:39:32

6

myfile.good()在讀取失敗後變爲false。與myfile.eof()相同。

你想要什麼基本上是:

myfile >> name; 
myfile >> phone; 
if (!myfile.good()) break; 

這樣就可以縮短爲:

if (!(myfile >> name >> phone)) break; 

或最後:

while (myfile >> name >> phone) { ... } 
1

iostream狀態不是預測性的。它報告前一個操作的結果 ,而不是下一個(無論如何都不可能實現 )。 myfile.good()甚至沒有可靠的指標 以前的操作結果:如果操作失敗,那麼 將爲false,但如果操作成功,則不一定爲 爲真。忘記那個功能。

使用流可以充當布爾值的事實來測試 先前操作的成功。一旦你失敗了,你可以使用eof(), 和bad()來確定爲什麼(但是關於eof(),僅在 失敗之後--- eof()可能返回true,即使之前的操作 成功)。因此:

while (myfile >> name >> phone) { 
    // ... 
} 
if (myfile.bad()) { 
    std::cerr << "Hardware read error" << std::endl; 
} else if (!myfile.eof()) { 
    std::cerr << "Format error in file" << std::endl; 
}