2012-09-22 64 views
0

stringstream似乎總是當我打電話stringstream::ignore()失敗,即使這調用stringstream::clear()後進行:字符串流::忽略(INT_MAX,「 n」)導致流失敗

#include <iostream> 
#include <fstream> 
#include <sstream> 
#include <string> 
#include <cassert> 

using namespace std; 

int main() { 
    int a, b; 
    stringstream ss; 
    string str; 
    ifstream inFile("file.txt"); 
    if(!inFile) { 
     cerr << "Fatal: Cannot open input file." << endl; 
     exit(1); 
    } 

    while(getline(inFile, str)) { 
     ss << str;    // read string into ss 
     ss >> a >> b;    // stream fails trying to store string into int 

     ss.clear();    // reset stream state 
     assert(ss.good());  // assertion succeeds 

     ss.ignore(INT_MAX, '\n'); // ignore content to next newline 
     assert(ss.good());  // assertion fails, why? 
    } 

    return 0; 
} 

file.txt包含以下文本:

123 abc 
456 def 

爲什麼ss.ignore()ss.good()假的?

回答

1

std::endl輸出\n並刷新流。但是,stringstream::flush()是毫無意義的,什麼都不做。 flush僅當底層緩衝區與終端等輸出設備綁定時纔有意義,但stringstream無處可用。如果您想清除串流的內容,請改爲ss.str("");。不過,我可能會在代碼更改爲以下:

while(getline(inFile, str)) { 
    ss.str(str);    // call ss.str() to assign a new string to the stringstream 
    if(!ss >> a >> b)   // check if stream fails trying to store string into int 
    { 
     ss.clear();   // Read failed, so reset stream state 
    } 
    else 
    { 
     // Read successful 
    } 
    // Do other stuff 
} 

另外,如果要插入一個新行到stringstream的,只是做ss << '\n';,不叫std::endl

+1

最後一句:'std :: ends'不會將'\ n'放入'\ 0' – PiotrNycz

+0

空字符可能會導致意外的行爲。 – bwDraco

+0

@PiotrNycz:謝謝,糾正。 –

0

原來在ss的末尾沒有換行符。執行以下語句後:

getline(infile, str); 
ss << str; 

ss將不包含換行符,因爲getline()不換行字符添加到存儲在第二個參數字符串的結尾。其結果是,當執行這樣的說法:因爲到達流的末尾沒有找到一個換行符停在

ss.ignore(INT_MAX, '\n'); 

流失敗。


ss.ignore()如果ss.str()用於存儲該字符串,它取代了流的整個內容是沒有必要的。 如果數據流失敗,應該重置它,並將其內容設置爲空字符串""。或者,可以使用ss.ignore(),但只有在數據讀取後立即將新行字符插入流中,以便它不會導致流失敗—,但是如果流的內容較晚,則這將是多餘的使用ss.str()設置爲另一個值。

文件的下一行的成功讀取可通過調用ss.clear()流被分配到文件的下一行的內容之前,由於上述流的舊內容上ss.str()覆蓋來保證。流狀態可以是在循環的開始復位,即使流後在循環失敗不會發生問題:

while(getline(inFile, str)) { 
    ss.clear(); // make sure stream is good 
    ss.str(str); // overwrite contents of stream with str 
    ss >> a >> b; 
    // Even if the stream fails after this line, the stream is reset before each 
    // line is stored into the stream, and no problems should occur while reading 
    // and parsing subsequent lines in the file. 

    // Code to validate and store data from file... 
} 
+0

'flush()'對'stringstream'不做任何事情,也不需要使用'endl'或'ignore',查看我的答案。 –

+0

@JesseGood:我剛剛糾正了我的答案。 – bwDraco

+0

看起來更好。另外,我不會在每個循環中調用'ss.clear()',而是'if(!ss >> a >> b)ss.clear();'所以只有當流失敗時才調用它(我改變了我的答案也反映了這一點)。 –