C++ostringstream&ofstream c ofstream 頭文件
//simple example
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
void test()
{
//ostringstream oss;
//oss.str("abc");
ostringstream oss("abc");
cout<< oss.str()<< endl;
oss<< 8 <<endl;
oss<< 3.14<< endl;
oss<< " ok ."<< endl;
cout<< oss.str()<< endl;
oss<< 8 <<" "<< 3.14<< ""<< " ok ."<< endl;
cout<< oss.str()<< endl;
}
int main(int argc, char* argv[])
{
test();
return0;
}
如果想獲取格式化好的字符串,通過ostringstream::str()函數(shù)就可以返回一個string對象, 調用string::c_str()或string::data()函數(shù)就可以獲得一個指向字符緩沖的char*變量.
stringstream顧名思義是字符串流,所有輸入其中的非字符類型如整形變量,浮點數(shù)都將被轉換成字符串。C++為什么不提供二進制流呢?我想將對象序列化后的數(shù)據(jù)放入到一個二進制流中,然后將流緩沖保存在數(shù)據(jù)庫中。我發(fā)現(xiàn)將binary_oarchive同stringstream結合起來使用有問題,對象在內存中的原始數(shù)據(jù)中會有許多0,而0又剛好是字符串結束的標志。解決這個問題我想到兩個辦法,如果將對象序列化后的數(shù)據(jù)保存到一個二進制文件中,然后再將文件的所有內容保存到數(shù)據(jù)庫中,但是這種方法效率應該很低;另外一種思路就是自己實現(xiàn)一個二進制流類,可以仿照stringstream來實現(xiàn),因為涉及到底層的讀寫函數(shù)都在basic_streambuf對象中,因此需要實現(xiàn)這個類的主要成員函數(shù),另外需要實現(xiàn)一個類似于basic_ostringstream的類以向外提供接口,并融入流系統(tǒng)中。 花了點時間研究了下ostringstream的實現(xiàn)(VS2008),發(fā)現(xiàn)事情遠沒有我想象的這么簡單。ostringstream相關的靜態(tài)結構類圖如下: 往stringstream的數(shù)據(jù)類型可以分為數(shù)字和字符串兩種,其中數(shù)字包括bool,int,float/double等幾種。針對數(shù)字和字符串的處理流程是不一樣的,數(shù)字要被轉變成字符類型,而字符串則不需要轉變。對數(shù)字的處理交給num_put類,比如輸入一個整型變量時,相關的處理代碼如下:_VIRTUAL _OutIt __CLR_OR_THIS_CALL do_put(_OutIt _Dest,ios_base& _Iosbase, _Elem _Fill, long _Val)const{ // put formatted long to _Destconst size_t _Buf_size = 2 * _MAX_INT_DIG;char _Buf[_Buf_size], _Fmt[6];return (_Iput(_Dest, _Iosbase, _Fill, _Buf,::sprintf_s(_Buf, _Buf_size, _Ifmt(_Fmt,"ld",_Iosbase.flags()), _Val)));} 上面的_Dest是一個用來操作basic_streambuf的迭代器,_Iosbase應該是用來指明進制的,_Fill應該是用來控制格式的,呵呵,_Val是我最能確定的,它便是要保存的變量值。用紅色標注的便是將數(shù)字轉變成字符的代碼,轉換后的字符串保存在_Buf中,_Iput將_Buf中的內容存入到_Dest迭代器封裝的basic_streambuf中。而在basic_streambuf定義了這樣兩個函數(shù):int_type sputc(_Elem _Ch){ // put a characterreturn (0 < _Pnavail()? _Traits::to_int_type(*_Pninc() = _Ch): overflow(_Traits::to_int_type(_Ch)));}
streamsize sputn(const _Elem *_Ptr, streamsize _Count){ // put _Count characters from array beginning at _Ptrreturn (xsputn(_Ptr, _Count));} sputc用于一次保存一個字符,sputn則可以一次保存_Count個字符,似乎由數(shù)字轉換而成的字符串都一個個調用sputc來保存,而字符串則調用sputn來保存。因為通過rdbuf方法可以獲取內部的basic_streambuf對象,所以也可以這樣使用ostringstream了:stringbuf *pbuf;ostringstream ss;
pbuf=ss.rdbuf(); //獲得basic_streambuf對象pbuf->sputn ("Sample string",13);//向其中存入字符串cout <<pbuf->str() <<endl; 另外需要注意的一點是basic_stringbuf的str函數(shù)實現(xiàn)代碼如下:_Mystr __CLR_OR_THIS_CALL str() const{ // return string copy of character arrayif (!(_Mystate & _Constant)&& _Mysb::pptr() != 0){ // writable, make string from write buffer_Mystr _Str(_Mysb::pbase(), (_Seekhigh< _Mysb::pptr()? _Mysb::pptr() : _Seekhigh) -_Mysb::pbase());return (_Str);}else if (!(_Mystate & _Noread)&& _Mysb::gptr() != 0){ // readable, make string from read buffer_Mystr _Str(_Mysb::eback(), _Mysb::egptr() -_Mysb::eback());return (_Str);}else{ // inaccessible, return empty string_Mystr _Nul;return (_Nul);}} 正常情況下,str函數(shù)會生成一個string對象,然后將其返回,所以“sstream.str().push_back('a');”并不能改變ostringstream的內容。"sstream.str().c_str()"獲得的也并不是stringstream緩沖的地址。 再分析下ofstream吧,我想看看它是如果操作二進制文件的。ofstream的結構同ostringstream是非常類似的,只不過ostringstream中的basic_stringbuf被替換成basic_filebuf而已。ofstream的使用方法如下:ofstream fout("test.dat",ios_base::binary);
int number = 30;
fout << number;
fout.write((char *)(&number),sizeof(number));
fout.close(); 我居然不知道如果想直接以二進制的方式保存數(shù)字的話只能使用ofstream的write方法,真是羞愧啊。如果使用"<<"仍然會以字符的形式保存數(shù)字,即便在構造函數(shù)中指明"ios::binary"也不行。跟進去看了看,發(fā)現(xiàn)保存的流程同ostringstream也是非常相似的,使用"<<"保存除了最后文件操作不同之外,前面的代碼都是一樣的;而write也沒有什么神奇之處,它調用basic_streambuf::sputn來保存數(shù)字。受fstream啟發(fā),我發(fā)現(xiàn)ostringstream同樣有read和write方法,可以直接保存一個內存塊(其實也可以直接使用sputn和sgetn來保存內存塊),但用起來卻有點小小的意外。因為ostringstream以空格分隔數(shù)據(jù)單元。stringstream sstream("fu zhijie 77");
sstream >> str1; //"fu"
sstream >> str2;//"zhijie"
sstream >> num; //77 接著我做了一個測試,代碼如下:int number = 30;
stringstream ss;ss << "Sample string";
ss.write((char *)(&number),sizeof(number));
string str;
ss >> str; //"Sample"
cout << str<< endl;
ss >> str;//"string..",這個字符串就要出錯了
cout << str<< endl;
int num;
ss.read((char*)&num, 4);//什么也得不到,num沒有被初始化
cout << num<< endl; 看下緩沖的內容發(fā)現(xiàn),number確實以"1e 00 0000"的二進制方式放置在"Samplestring"的后面,第二次取"string"的時候就要出錯了,因為要么取到空格處結束,要么到"0"處結束,這樣"1e"就被附到"string"的后面了,所以第二次將輸出"string"帶一個黑三角形。我又突發(fā)靈感,我想每次使用write寫數(shù)字時,先寫一個空格進去不就ok了嗎?結果發(fā)現(xiàn)空格會被當作數(shù)字的一部分,整型本來只有四個字節(jié),這里卻生生讀出五個字節(jié)來,"201e 00 00 00"對應的十進制數(shù)是7712,還是得不到正確結果。處理"Samplestring"時,中間那個空格肯定要在某個地方去除的,但是我沒有找到相應的代碼??磥韺stringstream同時使用"<<"和write是件很危險的事情。哎,如果每個字符串前面使用一個數(shù)字記錄字符串的長度就好啦~~最后感覺C++流系統(tǒng)給開發(fā)者留的擴展余地并不大,開發(fā)者直接使用的流均派生自istream和ostream,比如ostream的聲明如下:template<class _Elem,
class _Traits>
class basic_ostream
: virtual publicbasic_ios<_Elem, _Traits>
{// control insertions into astream buffer
public:
typedef basic_ostream<_Elem,_Traits> _Myt;
typedef basic_ios<_Elem,_Traits> _Myios;
typedef basic_streambuf<_Elem,_Traits> _Mysb;
typedef ostreambuf_iterator<_Elem,_Traits> _Iter;
typedef num_put<_Elem,_Iter> _Nput;..................}這里都限定只能使用basic_streambuf了,而開發(fā)者自定義想實現(xiàn)自己的streambuf就不容易融入整個系統(tǒng)了,如果將這個類型作為模板實例化參數(shù)就好了?。豢赡苁菫榱颂岣咝?,整個體系中很少使用虛函數(shù),這也限制了擴展性。
更多閱讀

Windows 7中清理c盤方法 c盤windows文件夾清理
裝完Win7 C盤本來還有50G的空余空間,可沒過多久就只剩了1、2G了,這種情況經(jīng)常出現(xiàn)。那么究竟我們電腦的C盤里有些什么東西在作怪,怎樣才能簡單方便的清除它們,下面就讓我們來一起看一下C盤的奧秘吧。Windows 7中清理c盤方法——工具/原

刪除文件函數(shù)和文件更名函數(shù) c語言刪除文件函數(shù)
1. 刪除文件函數(shù)(remove())使用函數(shù)remove(char *filename);可刪除文件filename,filename可以帶路徑名。函數(shù)執(zhí)行成功,返回0值;否則,返回-1,且錯誤標志errno取下列兩個值之一:ENOENT(表示文件不存在)或EACCES(表示拒絕存取)。例10.15

c盤里哪些文件可以刪除 c盤中哪些文件可以刪除
c盤里哪些文件可以刪除——簡介C盤一般是系統(tǒng)的安裝位置,時間長久之后C盤變得越來越小,系統(tǒng)的運行速度就會受到影響。我們可以通過一些方法刪除C盤中不需要的文件,你可以自行刪除,也可以利用防護優(yōu)化軟件清理垃圾文件。c盤里哪些文件可

C盤window文件里哪些文件可以刪除,清理的 - 電腦城 - 海員聯(lián) c盤清理工具 window10
C盤window文件里哪些文件可以刪除,清理的一般人們在安裝系統(tǒng)并全部打補丁后,會給系統(tǒng)減肥,也就是要刪除沒用的文件。什么可以刪除呢?1)刪除不需要的驅動文件:在WINDOWSDRIVER Cachei386driver.cab文件刪除,可以節(jié)省73MB的空間。2)刪除備用

C盤里文件夾的用途 c盤中的windows文件夾
你知道c盤的每個文件是干什么用的嗎?1. Documents and Settings 是什么文件?答案:是系統(tǒng)用戶設置文件夾,包括各個用戶的文檔、收藏夾、上網(wǎng)瀏覽信息、配置文件等。注意:這里面的東西不要隨便刪除,這保存著所有用戶的文檔和賬戶設置,如果刪
愛華網(wǎng)