2012-03-30 29 views
6

下面的代碼不像我所期望的那樣運行。請幫我理解它是如何工作的。ifstream的複製算法

#include <algorithm> 
#include <iterator> 
#include <fstream> 
#include <vector> 
#include <string> 
using namespace std; 

struct user 
{ 
     string name; 
     string age; 
     string id; 
}; 

istream& operator>>(istream& is, user& s) 
{ 
     getline(is, s.name, ':'); 
     getline(is, s.age, ':'); 
     getline(is, s.id); 

     return is; 
} 

int main(int argc, char* argv[]) 
{ 
     ifstream file("file.txt"); 
     vector<user> vec; 
     copy(istream_iterator<user>(file), istream_iterator<user>(), back_inserter(vec)); 

     return 0; 
} 

我的運營商定製>>被稱爲兩次,但我希望它被稱爲只有一次,因爲內容是:

約翰:40:21-5821-0

+1

你怎麼知道它被調用兩次?檢查調試器?你在矢量中得到兩個條目?如果最後一個,兩個條目是相同的? – 2012-03-30 22:49:35

+1

+1,最近出現了同樣的問題......由於某種原因,copy代碼中的迭代器增量導致了讀取,而不是取消引用,因此它執行的讀取次數太多。也就是說,您的'operator >>'需要在前兩個'getline'操作後檢查狀態! – 2012-03-30 22:50:30

+0

無需擔心不檢查返回值的I/O代碼。您必須*總是*檢查I/O操作的返回值。 – 2012-03-30 23:00:08

回答

3

一般情況下,讀取整個文件,直到讀取失敗。然後你知道出了什麼問題,或者你知道了。無論哪種方式,直到您閱讀失敗後才能知道您已達到文件末尾。由於第一個成功,它必須再次嘗試,以確定是否有第二個元素。這樣做的psudocode是

while(in_stream >> object) { 
    myvector.push_back(object); 
} 

另外請注意,這是「地道」的方式在價值觀的整個文件中讀取。如果您正在檢查eoffailbad,那麼您的代碼可能是錯誤的。

也就是說,你的istream& operator>>(istream& is, user& s)函數就好了。第二次調用時,第一個getline將失敗,將流設置爲不良狀態(eof),接下來的兩個getline也將失敗,並且它將返回該流,並且所有內容都可以正常工作。請記住,任何或所有這些變量可能會成爲完全廢話,因爲讀取失敗。