2012-09-22 32 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();'所以只有当流失败时才调用它(我改变了我的答案也反映了这一点)。 –