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

stringstream::ignore(INT_MAX, ' ') causes stream to fail

本文关键字:失败 流失 INT MAX stringstream ignore      更新时间:2023-10-16

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()之后为false?

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

原来ss的末尾没有换行符。执行以下语句后:

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

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

ss.ignore(INT_MAX, 'n');

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

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

ss.ignore(),该字符串将替换流的全部内容如果流失败,则应将其重置,并将其内容设置为空字符串""。或者,也可以使用ss.ignore(),但前提是在读取数据后立即将换行符插入流中,以免导致流失败—但是如果稍后使用CCD_ 22将流的内容设置为另一个值

在流被分配文件下一行的内容之前,可以通过调用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...
}