程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 你有被stringstream坑過嗎?

你有被stringstream坑過嗎?

編輯:C++入門知識

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]
<P>#include <sstream> 
#include <stdio.h>  
using namespace std; 
int main() 

    stringstream ss; 
    string result; 
    int n=1; 
    ss.clear();                                                                                                                                                                   
    ss<<n; 
    ss>>result; 
    printf("result : %s, str : %s\n", result.c_str(), ss.str().c_str());</P><P>    n=2; 
    ss.clear(); 
    ss<<n; 
    ss>>result; 
    printf("result : %s, str : %s\n", result.c_str(), ss.str().c_str());</P><P>    n=3; 
    ss.str(""); 
    ss<<n; 
    ss>>result; 
    printf("result : %s, str : %s\n", result.c_str(), ss.str().c_str());</P><P>    n=4; 
    ss.clear(); 
    ss.str(""); 
    ss<<n; 
    ss>>result; 
    printf("result : %s, str : %s\n", result.c_str(), ss.str().c_str()); 
}</P> 

#include <sstream>
#include <stdio.h>
using namespace std;
int main()
{
    stringstream ss;
    string result;
    int n=1;
    ss.clear();                                                                                                                                                                 
    ss<<n;
    ss>>result;
    printf("result : %s, str : %s\n", result.c_str(), ss.str().c_str());    n=2;
    ss.clear();
    ss<<n;
    ss>>result;
    printf("result : %s, str : %s\n", result.c_str(), ss.str().c_str());    n=3;
    ss.str("");
    ss<<n;
    ss>>result;
    printf("result : %s, str : %s\n", result.c_str(), ss.str().c_str());    n=4;
    ss.clear();
    ss.str("");
    ss<<n;
    ss>>result;
    printf("result : %s, str : %s\n", result.c_str(), ss.str().c_str());
}
 

測試結果:
result : 1, str : 1
result : 2, str : 12 // 調用了clear(), 沒有調用str(""), 結果錯誤.
result : 2, str :    // 調用了 str(""), 沒有調用clear(), 結果錯誤.
result : 4, str : 4 // 調用了 clear()和str(""), 結果正確.

 

附上str("")和str()的內部實現:


[cpp]
 /** 
   *  @brief  Setting a new buffer.
   *  @param  s  The string to use as a new sequence.
   *   
   *  Deallocates any previous stored sequence, then copies @a s to
   *  use as a new one.
  */   
  void 
  str(const __string_type& __s) 
  {    
// Cannot use _M_string = __s, since v3 strings are COW.  
_M_string.assign(__s.data(), __s.size()); 
_M_stringbuf_init(_M_mode); 
  } 

      /**
       *  @brief  Setting a new buffer.
       *  @param  s  The string to use as a new sequence.
       *  
       *  Deallocates any previous stored sequence, then copies @a s to
       *  use as a new one.
      */ 
      void
      str(const __string_type& __s)
      {  
    // Cannot use _M_string = __s, since v3 strings are COW.
    _M_string.assign(__s.data(), __s.size());
    _M_stringbuf_init(_M_mode);
      }
 

[cpp]
  // Get and set:  
  /**
   *  @brief  Copying out the string buffer.
   *  @return  A copy of one of the underlying sequences.
   *
   *  "If the buffer is only created in input mode, the underlying
   *  character sequence is equal to the input sequence; otherwise, it
   *  is equal to the output sequence." [27.7.1.2]/1
  */ 
  __string_type 
  str() const 
  { 
__string_type __ret; 
if (this->pptr()) 
  { 
    // The current egptr() may not be the actual string end.  
    if (this->pptr() > this->egptr()) 
      __ret = __string_type(this->pbase(), this->pptr()); 
    else 
      __ret = __string_type(this->pbase(), this->egptr()); 
  } 
else 
  __ret = _M_string; 
return __ret; 
  } 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved