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()
为假?
答案 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()