第二章 stringstream的使用

如果按照內容來給一個標題的話,那麼這一講的內容其實是上一講的後續部分,所以都屬於C++標準流一類,但是又礙於我們這不是寫書,而是按照文章來推送,所以這算是一個新的章節,然儘管如此,這依然算是C++的流的介紹,所以,在上一章文章中我們瞭解了C++標準流的用法後那麼我們現在從文件流說起。

程序無非是數據的操作,最常用的莫過於數據的讀寫了,還記得我們在上一講的內容中使用自定義的流擴展了一個文件流——FileOStream,該類繼承至MyStrIobase,當然我們可以直接繼承至OStream,好吧,想想為什麼要繼承至OStream,繼承至OStream的優勢又是什麼。

我們不對FileOstream進行討論,至少大家已經知道了C++標準流背後的一些原理,所以我們這一講的內容將是站在上一講的基礎上來對fstream和stream的探索。

從fstream說起

在C++標準庫中,fstream繼承至iostream,所以iostream該有的操作他都有,fstream還具有iostream不具有的能力——文件的度讀寫。

如同上一講的內容,文件的讀寫簡單點說就是將數據發送到指定的目的地或者是從指定的地方將數據取回來,所以,我們可以這麼來解讀iostream所幹的事——將這個目的地給固定了,而fstream卻可以自由指定這個目的地——文件,對於文件我們可以使用構造函數來指定,同樣可以使用open接口來重定向:

//+-----------------------

#include

int main(){

std::ofstream outFile("1.txt",std::ios::out);

outFile<

outFile.close();

outFile.open("2.txt",std::ios::out);

outFile<

outFile.close();

std::ifstream inFile("1.txt",std::ios::in);

std::string str;

std::getline(inFile,str);

std::cout<

inFile.close();

return 0;

}

//+------------------------

從上面的代碼中,我們可以看到,我們可以通過構造函數來打開文件,同樣也可以通過提供的成員函數open來打開文件,當我們寫完數據之後我們可以使用close來關閉文件,關閉當前文件後又可以打開其他文件,ofstream用來將數據寫入文件,ifstream用來從文件中讀取,所以,有了第一章的基礎後來使用fstream是非常簡單的,當然或許我們要說說的是對於二進制文件的讀寫,對於二進制數據還記得我們上一講中說到的write函數嗎?

//+-----------------------

ostream& write(const char*,streamsize);

//+-----------------------

當時我們說這個函數可以用來處理字符串,其實它不只是能夠處理字符串,他能夠處理一切數據,為什麼這麼說呢?首先,它的第一個參數是一個char的指針,第二個參數是一個大小,而char*可以轉換為任意數據的指針,同樣任意數據都可以轉換char*,比如:

//+-----------------------

int main(){

int a = 10;

char* ch = (char*)(&a);

int d = *(int*)(ch);

std::cout<

return 0;

}

//+-----------------------

我們將一個int的對象存儲在一個char*中然後又再取出來,數據得到很好的還原。我們再來看一些更為複雜的:

//+-----------------------

struct Test{

int a;

double b;

long long c;

};

int main(){

Test test = {10,20.0,1000LL};

char* ch = (char*)(&test);

Test test2 = *(Test*)(ch);

std::cout<

std::cout<

std::cout<

return 0;

}

//+------------------------

就算是複合類型也毫無問題,那麼我們是不是明白了write這個函數對於數據的讀寫能力的強大之處了呢?所以當我們要保存或是恢復一個對象的時候可以如下操作:

//+-----------------------

struct Test{

int a;

double b;

long long c;

};

int main(){

Test test = { 10, 20.0, 1000LL };

std::ofstream outFile("1.txt", std::ios::binary | std::ios::out);

outFile.write((char*)(&test), sizeof(Test));

outFile.close();

std::ifstream inFile("1.txt", std::ios::binary | std::ios::in);

char* ch = new char[sizeof(Test)];

memset(ch, 0, sizeof(Test));

inFile.read(ch, sizeof(Test));

inFile.close();

Test test2 = *(Test*)(ch);

std::cout << test2.a << std::endl;

std::cout << test.b << std::endl;

std::cout << test.c << std::endl;

return 0;

}

//+------------------------

我們可以將一個對象存儲在硬盤裡面需要的時候可以將他恢復出來,這就是fstream的write和read的妙用。上一講我們並沒有接觸過read,那麼read函數的原型如下:

//+-----------------------

ifsteram& read(char*, streamsize)

//+-----------------------

該函數的功能是從流中讀取指定大小的字節數據,數據填充在指定的地方——第一個參數指定的地址。

至此,使用C++讀寫文件對我們來說已經是很輕鬆的事了,那麼接下來我們來看看在C++流中我認為算是一個很高級的東西——stringstream。

stringstream,顧名思義就是字符串流,對於不少C++程序員來說這個這個組件可能用得比較少,或許可能很多人沒聽說過,比如就我就遇到有人不知道該流的存在,更別說用法了,因為這東西實在用得比較少,而且如果只是普通的使用C++的話stringstream是可以完全無視的。噢……既然可以被無視的東西為什麼我們這裡要說呢?而且更是將stringstream的使用來作為這一章的標題。好吧,原因很簡單,在我看來stringstream雖然不常用,但並不表示它沒用。

設想一個場景,假如有兩個函數,兩個函數需求的參數類型各不相同,但如今我們會用到這兩個函數,為了簡便操作,我們將兩個函數封裝成一個函數:

每天會更新論文和視頻,還有如果想學習c++知識在晚上8.30免費觀看這個直播:https://ke.qq.com/course/131973#tuin=b52b9a80


分享到:


相關文章: