c++ stringstream类 clear函数的真正用途

许多博客都有提到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/




 

posted on 2016-02-05 12:40  Elenno  阅读(13223)  评论(0编辑  收藏  举报

导航