stringstream的clear函数与缓冲区清空
头文件<sstream>
c++中引入了流的概念,通过流来实现字符串和数字的转换。
定义了三个类:istringstream、ostringstream 和 stringstream,分别用来进行流的输入、输出和输入输出操作。
C++没有split函数,可以用istringstreams实现空格分割字符串。如下:
string str="i am a boy";
istringstream is(str);
string s;
while(is>>s)
cout<<s<<endl;
今天用stringstream做数据转换时遇到问题,代码如下:
char data;
char elem;
string str;
string code;
ifstream ifs("test.txt");
stringstream ss;
while(!ifs.eof()&&getline(ifs,str))
{
cout<<str<<endl; //验证是否成功读入字符串
ss<<str; //输入字符串到流中
ss>>data;
ss>>elem; //跳过符号
ss>>code;
cout<<data<<" "<<code<<endl;//验证结果
}
预期结果为:
A:344
A 34
C:54
c 54
实际结果为:
A:344
A 344
C:54
A 344
明明str显示已经成功读入字符串,但结果出现错误。
然后通过输出ss.str()发现,后面的字符串并没有输入到流中。
通过查找资料,原因在于
在第一次调用完operator<<和operator>>后,来到了end-of-file的位置,此时stringstream会为其设置一个eofbit的标记位,标记其为已经到达eof。 当stringstream设置了eofbit,任何读取eof的操作都会失败,同时,会设置failbit的标记位,标记为失败状态。所以后面的操作都失败了。
clear函数的作用就是清除掉所有的error state,所以在代码前面加一个ss.clear()即可达到预期结果。
这里需要注意的是,clear函数是清除流的状态而不是清空缓冲区,而stringstream多次使用后占用的内存没有释放会容易出现问题,所以我们需要用到函数
void str ( const string & s )
该方法是重新给stringstream赋新值。
我们可以用stringstream.str("")来清空stringstream。
所以在重复使用stringstream时,最好连同stringstream.clear()、stringstream.str("")一起使用。