许多博客都有提到stringstream的清空,不应该调用clear,而是要调用str(""),传入一个空字符串来让其清空内容。
然而我将提到的是clear的真正用法,究竟什么情况下需要用到clear
先来看一个stack overflow上的问题(http://stackoverflow.com/questions/35080342/using-two-string-streams-but-not-getting-same-result)
我将其简化为以下代码:
int main() { string line = "1 2 3 4 5"; stringstream s1(line); string temp; int toAdd; stringstream s2; while (s1 >> temp) { cout << "temp:" << temp << endl; s2 << temp; cout << "s2.str: " << s2.str() << endl; s2 >> toAdd; cout << "toAdd:" << toAdd << endl; s2.str(""); } return 0; }
这个代码的原意是要把line中的字符串形式的1 2 3 4 5一个一个地转成int并输出,所以我们期望的toAdd的输出应该是1 2 3 4 5,但结果却是 1 1 1 1 1, 如下图
可以从s2.str:这句输出中看到, 只有第一次是正常地把temp输入进s2,后面的都失败了。
原因在于, s2在第一次调用完operator<<和operator>>后,来到了end-of-file的位置,此时stringstream会为其设置一个eofbit的标记位,标记其为已经到达eof。查文档得知, 当stringstream设置了eofbit,任何读取eof的操作都会失败,同时,会设置failbit的标记位,标记为失败状态。所以后面的操作都失败了,toAdd的值一直都是1。
Operations that attempt to read at the End-of-File fail, and thus both the eofbit and the failbit end up set. This function can be used to check whether the failure is due to reaching the End-of-File or to some other reason.
clear函数:
原型: void clear (iostate state = goodbit);
标志位一共有4种, goodbit, eofbit, failbit, badbit
clear可以清除掉所有的error state
int main() { string line = "1 2 3 4 5"; stringstream s1(line); string temp; int toAdd; stringstream s2; while (s1 >> temp) { cout << "temp:" << temp << endl; s2 << temp; cout << "s2.str: " << s2.str() << endl; s2 >> toAdd; cout << "toAdd:" << toAdd << endl; s2.str(""); if (s2.eof()) { s2.clear(); cout << "s2.eof true" << endl; } } return 0; }
使用clear后, s2就可以正常地工作了,结果如下:
参考网站:http://www.cplusplus.com/reference/sstream/stringstream/
http://www.cplusplus.com/reference/ios/ios/clear/