你有被stringstream坑过吗?

转载 2016年05月31日 19:15:32

stringstream常用来安全的格式化若干个字符串,数值到一个缓冲区, 而不用担心溢出, 可以用来取代snprintf. 
但是很多人都在使用stringstream的时候遇到因为stringstream内部的缓冲区没有正确的清空导致的问题.

那么把stringstream类内部的缓冲区正确的清空方式是什么呢?
stringstream ss;
答案是: ss.str("") 方法.
另外,如果需要把格式化后的字符串通过>>输出到字符串, 必须每次都调用clear()方法!

所以, 保险期间, 每次缓冲区格式化后, 都通过clear(), str("") 两个函数都调用, 把stingstream类复位.


PS1: 网上有一些讨论, 说ss.str("")方法不管用, 而通过 ss.str().clear(); 这可能是c++标准库的实现方法不一致导致. 可以自行看下代码库引用的sstream文件的源码.
       在我的linux机器上, /usr/include/c++/4.1.0/sstream, 以及vs2008的实现, 都是和本文是一致的.
PS2: 注意str() 和 str("") 的区别
       str() 是返回内部缓冲区的一个copy, str("") 是清空内部缓冲区.

测试程序:

[cpp] view plain copy
  1. <p>#include <sstream>  
  2. #include <stdio.h>  
  3. using namespace std;  
  4. int main()  
  5. {  
  6.     stringstream ss;  
  7.     string result;  
  8.     int n=1;  
  9.     ss.clear();                                                                                                                                                                    
  10.     ss<<n;  
  11.     ss>>result;  
  12.     printf("result : %s, str : %s\n", result.c_str(), ss.str().c_str());</p><p>    n=2;  
  13.     ss.clear();  
  14.     ss<<n;  
  15.     ss>>result;  
  16.     printf("result : %s, str : %s\n", result.c_str(), ss.str().c_str());</p><p>    n=3;  
  17.     ss.str("");  
  18.     ss<<n;  
  19.     ss>>result;  
  20.     printf("result : %s, str : %s\n", result.c_str(), ss.str().c_str());</p><p>    n=4;  
  21.     ss.clear();  
  22.     ss.str("");  
  23.     ss<<n;  
  24.     ss>>result;  
  25.     printf("result : %s, str : %s\n", result.c_str(), ss.str().c_str());  
  26. }</p>  


 

测试结果:
result : 1, str : 1
result : 2, str : 12 // 调用了clear(), 没有调用str(""), 结果错误.
result : 2, str :    // 调用了 str(""), 没有调用clear(), 结果错误.
result : 4, str : 4 // 调用了 clear()和str(""), 结果正确.

 

附上str("")和str()的内部实现:

[cpp] view plain copy
  1.   /**  
  2.    *  @brief  Setting a new buffer. 
  3.    *  @param  s  The string to use as a new sequence. 
  4.    *    
  5.    *  Deallocates any previous stored sequence, then copies @a s to 
  6.    *  use as a new one. 
  7.   */    
  8.   void  
  9.   str(const __string_type& __s)  
  10.   {     
  11. // Cannot use _M_string = __s, since v3 strings are COW.  
  12. _M_string.assign(__s.data(), __s.size());  
  13. _M_stringbuf_init(_M_mode);  
  14.   }  


 

[cpp] view plain copy
  1.   // Get and set:  
  2.   /** 
  3.    *  @brief  Copying out the string buffer. 
  4.    *  @return  A copy of one of the underlying sequences. 
  5.    * 
  6.    *  "If the buffer is only created in input mode, the underlying 
  7.    *  character sequence is equal to the input sequence; otherwise, it 
  8.    *  is equal to the output sequence." [27.7.1.2]/1 
  9.   */  
  10.   __string_type  
  11.   str() const  
  12.   {  
  13. __string_type __ret;  
  14. if (this->pptr())  
  15.   {  
  16.     // The current egptr() may not be the actual string end.  
  17.     if (this->pptr() > this->egptr())  
  18.       __ret = __string_type(this->pbase(), this->pptr());  
  19.     else  
  20.       __ret = __string_type(this->pbase(), this->egptr());  
  21.   }  
  22. else  
  23.   __ret = _M_string;  
  24. return __ret;  
  25.   }  

你有被stringstream坑过吗?

stringstream常用来安全的格式化若干个字符串,数值到一个缓冲区, 而不用担心溢出, 可以用来取代snprintf. 但是很多人都在使用stringstream的时候遇到因为strings...
  • zdl1016
  • zdl1016
  • 2013年05月09日 16:04
  • 10453

Stringstream 缓冲区清空方法 和 复用StringStream 不是clear那么简单

最近编写
  • l631068264
  • l631068264
  • 2014年05月06日 12:40
  • 4025

字符流stringstream详解

以下内容转自:http://www.usidcbbs.com/read-htm-tid-1898.html C++引入了ostringstream、istringstream、stringstrea...
  • lanbing510
  • lanbing510
  • 2015年01月05日 15:11
  • 11121

你有被stringstream坑过吗?

stringstream常用来安全的格式化若干个字符串,数值到一个缓冲区, 而不用担心溢出, 可以用来取代snprintf. 但是很多人都在使用stringstream的时候遇到因为strings...
  • zdl1016
  • zdl1016
  • 2013年05月09日 16:04
  • 10453

stringstream的应用

  • 2011年01月14日 14:14
  • 41KB
  • 下载

Stringstream的用法 c++

  • 2013年05月19日 12:11
  • 48KB
  • 下载

[C/C++标准库]_[中级]_[使用stringstream作为内存流读取]

stringstream可作为内存流来使用,比如再需要处理文件,过滤内容后再输出到另一个文件里。内存流不需要操作文件指针,比较省时间和io....
  • infoworld
  • infoworld
  • 2014年06月10日 16:44
  • 5521

(转)C++ stringstream介绍,使用方法与例子

C++引入了ostringstream、istringstream、stringstream这三个类,要使用他们创建对象就必须包含sstream.h头文件。   istringstream类用于...
  • caihongshijie6
  • caihongshijie6
  • 2013年08月07日 13:52
  • 1370

stringstream与snprintf性能对比测试

最近发现服务中存在大量stringstream对象的创建,导致性能低下,于是对stringstream心生敬畏了,特地做了一下他和snprintf的性能比较测试实验,分别考察了下面四种选择在多线程环境...
  • wjj547670933
  • wjj547670933
  • 2015年03月13日 14:49
  • 888

用stringstream读取数据

思想: 全部读到一个字符串里,遇到","就换成空格,然后用这个字符串构造一个stringstream, 用>>读到数组里。 stringstream用法 分为istream和ostringstr...
  • chenwk891
  • chenwk891
  • 2013年11月15日 15:31
  • 1503
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:你有被stringstream坑过吗?
举报原因:
原因补充:

(最多只允许输入30个字)