文章目錄
-
-
- 1. stringbuf類介紹
-
- 1.1 stringbuf類構造函數
- 1.2 str函數
- 2. istringstream類
-
- 2.1 rdbuf函數
- 2.2 swap函數
- 3.ostringstream類和stringstream類
-
前文說過,istringstream是繼承于istream,ostringstream是繼承于ostream,而他們使用的緩沖區類是stringbuf。
關于這些類之間的關系,有興趣可以去檢視我之前的文章:
c++标準輸入輸出流關系梳理
stringbuf類緩沖區使用一個std::string類作為存儲媒體,然後根據構造時的讀寫模式來對string類進行讀寫。
小貼士:explicit用來防止由構造函數定義的隐式轉換。
//根據傳入的讀寫标示構造一個擁有空string的緩沖區,預設可讀可寫
explicit basic_stringbuf(ios_base::openmode __mode = ios_base::in | ios_base::out)
: __streambuf_type(), _M_mode(__mode), _M_string()
{ }
//複制一個已有的string作為緩沖區内容,且根據__mode來指定可讀、可寫或者讀寫,預設可讀可寫
explicit basic_stringbuf(const __string_type& __str,
ios_base::openmode __mode = ios_base::in | ios_base::out)
: __streambuf_type(), _M_mode(), _M_string(__str.data(), __str.size())
{ _M_stringbuf_init(__mode); }
使用例子如下:
#include <sstream>
using namespace std;
int main()
{
stringbuf *buf = new stringbuf(ios_base::in);//構造一個可寫的空stringbuf
string str("my name is haha");
stringbuf *bufStr = new stringbuf(str, ios_base::out);
if ( buf != nullptr )
{
delete buf;
}
if ( bufStr != nullptr )
{
delete bufStr;
}
return 0;
}
str函數原型如下:
//擷取string内容
__string_type
str() const;
//參數__s中内容初始化為目前緩沖區string
void
str(const __string_type& __s);
使用案例如下:
#include <sstream>
#include <iostream>
using namespace std;
int main()
{
stringbuf *buf = new stringbuf(ios_base::in);
string str("my name is haha");
stringbuf *bufStr = new stringbuf(str, ios_base::out);
cout << bufStr->str() << endl;
buf->str(string("my name is not haha"));
cout << buf->str() << endl;
if ( buf != nullptr )
{
delete buf;
}
if ( bufStr != nullptr )
{
delete bufStr;
}
return 0;
}
還有其他函數這裡就不多做介紹了,理論上來講,我們并不會直接使用stringbuf,因為它隻是一個工具人,是藏于暗中滴,大多數時候,我們都是直接使用istringstream和ostringstream。
前文說過,實際上istringstream全名應該是basic_istringstream,istringstream隻是basic_istringstream的一個char類型執行個體,下面還是直接使用istringstream來進行代指。
istringstream的構造函數與stringbuf的參數以及類型一模一樣,是以直接按照stringbuf的構造函數用法一樣使用即可,隻是流打開模式上而言,istringstream預設是ios_base::in。
截取構造函數原型如下:
explicit
basic_istringstream(ios_base::openmode __mode = ios_base::in)
: __istream_type(), _M_stringbuf(__mode | ios_base::in)
{ this->init(&_M_stringbuf); }
explicit
basic_istringstream(const __string_type& __str,
ios_base::openmode __mode = ios_base::in)
: __istream_type(), _M_stringbuf(__str, __mode | ios_base::in)
{ this->init(&_M_stringbuf); }
另外istringstream的str函數也是與stringbuf一樣,傳回了string對象,這裡不再多說。
rdbuf函數原型如下:
//傳回一個指向stringbuf對象的指針
__stringbuf_type*
rdbuf() const
{ return const_cast<__stringbuf_type*>(&_M_stringbuf); }
rdbuf使用案例如下:
#include <sstream>
#include <iostream>
using namespace std;
int main()
{
istringstream istr("istringstream", ios_base::in);
cout << "string is " << istr.str() << endl;
cout << "string's len is " << istr.rdbuf()->in_avail() << endl;
return 0;
}
這裡也順便展示了一下str函數的用法,in_avail是streambuf類裡面的一個函數,用于傳回目前緩沖區長度。
編譯後執行結果如下:
[root@mylinux ~]# ./a.out
string is istringstream
string's len is 13
[root@mylinux ~]#
swap函數原型如下:
//用于交換兩個istringstream内容
void swap(basic_istringstream& __rhs);
用法如下:
#include <sstream>
#include <iostream>
using namespace std;
int main()
{
istringstream istr1("lilei");
istringstream istr2("hanmeimei");
istr1.swap(istr2);
cout << "istr1 is " << istr1.str() << endl;
cout << "istr2 is " << istr2.str() << endl;
return 0;
}
編譯後輸出結果如下:
[root@mylinux ~]# ./a.out
istr1 is hanmeimei
istr2 is lilei
[root@mylinux ~]#
可以看到istr1和istr2兩個對象的内容是完全交換了。
ostringstream用于往string寫入資料,除了構造的時候,預設的打開模式是ios_base::out,其他所有函數都與istringstream一樣,且用法也是一樣的,這裡不再多說。
截取其中一個構造函數原型如下:
//隻是構造函數預設參數不一樣,其他與istringstream是一樣的
explicit
basic_ostringstream(ios_base::openmode __mode = ios_base::out)
: __ostream_type(), _M_stringbuf(__mode | ios_base::out)
{ this->init(&_M_stringbuf); }
stringstream是繼承于iostream類,它除了構造函數預設模式不一樣,其他所有函數也與istringstream用法一樣
explicit
basic_stringstream(ios_base::openmode __m = ios_base::out | ios_base::in)
: __iostream_type(), _M_stringbuf(__m)
{ this->init(&_M_stringbuf); }