我有一个类似的代码,关于stringstream。我发现了一个奇怪的行为:
#include <iostream>
#include <fstream>
#include <sstream>
using namespace std;
int main()
{
int p, q;
fstream file;
string str;
stringstream sstr;
file.open("file.txt", ios::in);
if(file.is_open()) {
while(getline(file, str)) {
sstr << str;
sstr >> p >> q;
cout << p << ' ' << q << endl;
sstr.str("");
}
}
file.close();
return 0;
}
假设我将file.txt设为
4 5
0 2
在第一行中5
之后返回,第二行中返回2。该计划给了我:
4 5
4 5
表示未正确分配p
和q
。但我每次sstr.str()
检查时都会检查该行的正确字符串。
为什么stringstream有这样的行为?
答案 0 :(得分:3)
在读取第二个整数后,流处于非良好状态,因此您必须在恢复之前重置其错误状态。
你真正的错误是没有检查输入操作的返回值,或者你会立即发现它!
更简单的解决方案可能是不尝试重用相同的流,而是每轮重新创建它:
for (std::string line; std::getline(file, line); )
{
std::istringstream iss(line);
if (!(iss >> p >> q >> std::ws) || !iss.eof())
{
// parse error!
continue;
}
std::cout << "Input: [" << p << ", " << q << "]\n";
}
答案 1 :(得分:1)
当您阅读p
,然后q
时,您会到达流的末尾并设置标记eofbit
,您无法再执行任何操作了。
只需clear()
它,您的代码就会按预期运行。
但您可能希望直接使用file
,而file.close();
会在if
中有更好的位置:
fstream file;
file.open("file.txt", ios::in);
if(file.is_open()) {
int p, q;
while(file >> p >> q) {
cout << p << ' ' << q << endl;
}
file.close();
}
答案 2 :(得分:0)
您的代码有一些冗余行:fstream
可以在定义期间打开,并且不需要显式文件close()
,因为它会在main()
结束时自动销毁。
此外,在您的文件阅读循环中,如果您要为每一行初始化新的sstr << str
,则应将stringstream sstr(line);
行替换为stringstream
,这将构成以下行: sstr.str("");
也是多余的。
应用上述更正,以下是您的代码:
int main() {
int p, q;
fstream file("file.txt", ios::in);
// check status
if (!file) cerr << "Can't open input file!\n";
string line;
// read all the lines in the file
while(getline(file, line)) {
// initialize the stringstream with line
stringstream sstr(line);
// extract line contents (see Note)
while (sstr >> p >> q) {
// print extracted integers to standard output
cout <<"p: " << p <<" q: "<< q << endl;
}
}
return 0;
}
注意:行while (sstr >> p >> q)
假定一行只包含整数,用空格分隔。