stringstream :: ignore(INT_MAX,'\ n')导致流失败

时间:2012-09-22 05:36:56

标签: c++ stream stringstream

当我致电stringstream时,

stringstream::ignore()似乎总是失败,即使这是在致电stringstream::clear()后完成的:

#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.good()之后为什么ss.ignore()为假?

2 个答案:

答案 0 :(得分: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
}

此外,如果您想在字符串流中插入换行符,请执行ss << '\n';,不要拨打std::endl

答案 1 :(得分:0)

事实证明ss结束时没有新行。执行以下语句后:

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

ss将不包含换行符,因为getline()不会在存储到第二个参数的字符串末尾添加换行符。因此,执行此语句时:

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

流失败,因为它到达流的末尾而没有找到要停止的换行符。


如果ss.ignore()用于存储字符串,则不需要

ss.str(),该字符串将替换流的全部内容。 如果流失败,则应将其重置并将其内容设置为空字符串""。或者,可以使用ss.ignore(),但只要在读取数据后立即将新行字符插入到流中,这样就不会导致流失败 - 但如果内容不正确,则这将是多余的。稍后使用ss.str()将流设置为另一个值。

通过在为流分配文件的下一行内容之前调用ss.clear(),可以确保成功读取文件的下一行,因为流的旧内容将被覆盖{{ 1}}。流状态可以在循环开始时重置,即使流在循环中稍后失败也不会出现问题:

ss.str()