C++IO流之fstream,?stringstream使用小結(jié)
IO流
1. C語(yǔ)言IO
C語(yǔ)言中常用的輸入輸出函數(shù)有如下幾種:前者是格式化標(biāo)準(zhǔn)輸入輸出,后者是格式化文件輸入輸出,最后是格式化字符串輸入輸出。
函數(shù)名 | 內(nèi)容 | 備注 |
---|---|---|
scanf | 從標(biāo)準(zhǔn)輸入流(鍵盤(pán))讀取格式化的數(shù)據(jù) | 省略standard |
fscanf | 從所有輸入流讀取讀取格式化數(shù)據(jù) | f:file |
sscanf | 從字符串中讀取格式化的數(shù)據(jù) | s:string |
printf | 將格式化的數(shù)據(jù)輸出到標(biāo)準(zhǔn)輸出流(屏幕)上 | 省略standard |
fprintf | 將格式化數(shù)據(jù)輸出到所有輸出流上 | f:file |
sprintf | 將格式化的數(shù)據(jù)輸出到字符串中 | s:string |
文件的輸入輸出需要以下幾個(gè)函數(shù):
函數(shù)名 | 功能 | 適用范圍 |
---|---|---|
fopen | 打開(kāi)文件流 | 文件 |
fclose | 關(guān)閉文件流 | 文件 |
fscanf | 從所有輸入流讀取讀取格式化數(shù)據(jù) | 文件 |
fprintf | 將格式化數(shù)據(jù)輸出到所有輸出流上 | 文件 |
fread | 二進(jìn)制輸入 | 文件 |
fwrite | 二進(jìn)制輸出 | 文件 |
//文件開(kāi)關(guān) FILE* fopen (const char* filename, const char* mode); int fclose (FILE* stream); //格式化讀寫(xiě) int fprintf (FILE* stream, const char* format [, argument ]...); int fscanf (FILE* stream, const char* format [, argument ]...); //二進(jìn)制讀寫(xiě) size_t fwrite (const void* buffer, size_t size, size_t count, FILE* stream); size_t fread ( void* buffer, size_t size, size_t count, FILE* stream);
使用方式如下:
struct ServerInfo { char _ip[32]; int _port; friend ostream& operator<<(ostream& os, ServerInfo& info); friend ostream& operator>>(ostream& os, ServerInfo& info); }; //測(cè)試C語(yǔ)言二進(jìn)制讀寫(xiě) void TestC_Write_Bin() { ServerInfo info = { "192.168.1.1",80 }; FILE* fout = fopen("info.bin", "wb"); //assert(); fwrite(&info, sizeof(ServerInfo), 1, fout); fclose(fout); } void TestC_Read_Bin() { ServerInfo info; FILE* fin = fopen("info.bin", "rb"); fread(&info, sizeof(ServerInfo), 1, fin); printf("%s:%d", info._ip, info._port); fclose(fin); } //測(cè)試C語(yǔ)言字符讀寫(xiě) void TestC_Write_Text() { ServerInfo info = { "192.168.1.1",80 }; FILE* fout = fopen("info.txt", "w"); fprintf(fout, "%s %d", info._ip, info._port); fclose(fout); } void TestC_Read_Text() { ServerInfo info; FILE* fin = fopen("info.txt", "r"); fscanf(fin, "%s %d", &info._ip, &info._port); printf("%s:%d", info._ip, info._port); }
2. C++IO
C++ 標(biāo)準(zhǔn)庫(kù)提供了4個(gè)全局流對(duì)象cin
、cout
、cerr
、clog
。cout、cerr、clog 是 ostream 類的三個(gè)不同的對(duì)象。使用 cout 進(jìn)行標(biāo)準(zhǔn)輸出,使用 cin 進(jìn)行標(biāo)準(zhǔn)輸入。同時(shí) C++ 標(biāo)準(zhǔn)庫(kù)還提供了 cerr 用來(lái)進(jìn)行標(biāo)準(zhǔn)錯(cuò)誤的輸出,以及 clog 進(jìn)行日志的輸出。
2.1 C++標(biāo)準(zhǔn)IO流
cout
,cin
是ostream
,istream
類的對(duì)象,operator<<
,operator>>
分別是兩個(gè)對(duì)象的操作符重載成員函數(shù)。
C++輸出輸入可直接使用cout>>
和cin>>
,因?yàn)槠渲剌d了所有內(nèi)置類型,對(duì)于自定義類型需要自行重載操作符>>
和<<
。
cin >> a >> b;
operator<<
和operator>>
的返回值也是ostream&
或istream&
,因此支持連續(xù)輸入輸出,又是一次函數(shù)調(diào)用。
cout/cin 取代 printf/scanf 的真正原因是 cout/cin 支持自定義類型,符合面向?qū)ο蟮乃枷搿?/p>
當(dāng)需要循環(huán)讀入數(shù)據(jù)時(shí),可以采用如下的方式:
string str; while (cin >> str) { ; }
從文檔中可以看到,operator>>
的返回值是istream
類型,這個(gè)對(duì)象類型是如何作真假判斷的呢?
原因是istream
類的對(duì)象支持一個(gè)操作符的重載函數(shù)叫operator bool
,C++98中叫operator void*
,C++11中叫operator bool
。
這是個(gè)特殊的運(yùn)算符重載函數(shù),該函數(shù)不允許限定返回類型,當(dāng)類型被當(dāng)作條件判斷時(shí),自動(dòng)調(diào)用并將返回值強(qiáng)轉(zhuǎn)為內(nèi)置的標(biāo)識(shí),該標(biāo)識(shí)如果為真就繼續(xù),如果為假就停止讀取。
2.2 C++文件IO流
采用面向?qū)ο蟮乃枷?,C++中文件指針被文件輸入輸出流對(duì)象ofstream
、ifstream
代替。
和fopen
的調(diào)用方式類似,創(chuàng)建輸入輸出流對(duì)象,調(diào)用其構(gòu)造函數(shù)傳入文件地址以及打開(kāi)模式。fclose
被析構(gòu)函數(shù)代替,且析構(gòu)函數(shù)可以自動(dòng)調(diào)用。
對(duì)象構(gòu)造函數(shù) | 解釋 |
---|---|
ofstream (const char fileName, ios_base::openmode mode=ios_base::out)* | 創(chuàng)建輸出流對(duì)象,并指定文件地址和打開(kāi)模式 |
ifstream (const char fileName, ios_base::openmode mode=ios_base::in)* | 創(chuàng)建輸入流對(duì)象,并指定文件地址 |
打開(kāi)模式變量的類型是ios_base::openmode
,該變量有如下幾個(gè)特定的值:
模式 | 解釋 |
---|---|
in | 文件讀取模式 |
out | 文件寫(xiě)入模式 |
binary | 二進(jìn)制文件模式 |
… |
常用的有如上幾種,該變量的值以二進(jìn)制位中的不同位為1來(lái)標(biāo)識(shí),也就是說(shuō)使用異或|
就可以組合起來(lái)用。
函數(shù) | 解釋 |
---|---|
istream& read(char s, streamsize n);* | read 接口是輸入流istream 對(duì)象的成員函數(shù),參數(shù)是變量和大小。 |
ostream& write(const char s , streamsize n);* | write 接口是輸出流ostream 對(duì)象的成員函數(shù),參數(shù)是寫(xiě)入變量和寫(xiě)入大小。 |
示例
使用一個(gè)ConfigManage
類來(lái)演示幾種文件讀寫(xiě)的方式。
struct ServerInfo { char _ip[32]; int _port; friend ostream& operator<<(ostream& os, ServerInfo& info); friend ostream& operator>>(ostream& os, ServerInfo& info); }; class ConfigManage { public: ConfigManage(const char* fileName) :_fileName(fileName) {} //二進(jìn)制寫(xiě)入 void WriteBin(ServerInfo& info) { ofstream ofs(_fileName.c_str(), ios_base::out | ios_base::binary); //創(chuàng)建輸出流對(duì)象 ofs.write((const char*)&info, sizeof(ServerInfo)); //調(diào)用write接口 } //二進(jìn)制讀取 void ReadBin(ServerInfo& info) { ifstream ifs(_fileName.c_str(), ios_base::in | ios_base::binary); ifs.read((char*)&info, sizeof(ServerInfo)); cout << info << endl; } private: string _fileName; };
讀寫(xiě)文件更常用的方式是以文本形式讀寫(xiě),因此就可以省略打開(kāi)模式參數(shù)。
ifstream
,ofstream
文件輸入輸出類中還繼承了iostream
的流插入<<
流提取>>
操作符,也就是對(duì)象ofs
和ifs
也可以使用<<
或>>
操作符。
struct ServerInfo { friend ostream& operator<<(ostream& os, ServerInfo& info); friend ostream& operator>>(ostream& os, ServerInfo& info); char _ip[32]; int _port; }; ostream& operator<<(ostream& os, ServerInfo& info) { os << info._ip << " " << info._port; return os; } istream& operator>>(istream& is, ServerInfo& info) { is >> info._ip >> info._port; return is; } //文本寫(xiě)入 void WriteText(ServerInfo& info) { ofstream ofs(_fileName.c_str()); //write ofs.write((const char*)&info, sizeof(ServerInfo)); //1. ofs << info._ip << info._port; //對(duì)象未重載<< //2. ofs << info; //對(duì)象已重載>> } //文本讀取 void ReadText(ServerInfo& info) { ifstream ifs(_fileName.c_str()); //read ifs.read((char*)&info, sizeof(ServerInfo)); //1. ofs << info._ip << info._port; //對(duì)象未重載<< //2. ifs >> info; //對(duì)象已重載>> cout << info << endl; }
具體調(diào)用方式則是如下:
void TestCPP_Write_Bin() { ServerInfo info = { "192.168.1.1",80 }; ConfigManage con("config.bin"); con.WriteBin(info); } void TestCPP_Read_Bin() { ServerInfo info; ConfigManage con("config.bin"); con.ReadBin(info); } void TestCPP_Write_Text() { ServerInfo info = { "192.168.1.1",80 }; ConfigManage con("config.bin"); con.WriteText(info); } void TestCPP_Read_Text() { ServerInfo info; ConfigManage con("config.bin"); con.ReadText(info); }
文件的輸入輸出流對(duì)象調(diào)用構(gòu)造函數(shù)時(shí)也可能會(huì)失敗,C++采取面向?qū)ο髵伄惓5男问健?/p>
2.3 C++ stringstream
在頭文件 下,有三個(gè)類:istringstream、ostringstream 和 stringstream,分別用來(lái)進(jìn)行字符串流的輸入、輸出和輸入輸出操作。
- 字符串流
ostringstream
可以將一個(gè)其他類型的數(shù)據(jù)轉(zhuǎn)化為字符串格式,該類中的成員函數(shù)str
可以返回轉(zhuǎn)出的字符串。 - 字符串流
istringstream
可以將一個(gè)字符串格式轉(zhuǎn)化其他類型的數(shù)據(jù),該類中的成員函數(shù)str
可以傳入需要轉(zhuǎn)化的字符串,或直接在構(gòu)造時(shí)傳入。
struct PersonInfo { string _name; int _age; friend ostream& operator<<(ostream& os, PersonInfo& info); friend istream& operator>>(istream& is, PersonInfo& info); }; //序列化 PersonInfo info1 = { string("zhangsan"), 20 }; ostringstream oss; //1. oss << info1._name << " " << info1._age; //對(duì)象未重載<< //2. oss << info1; string str = oss.str(); cout << str << endl; //反序列化 PersonInfo info2; istringstream iss(str); iss.str(str); //1. iss >> info2._name >> info2._age; //對(duì)象未重載>> //2. iss >> info2; cout << info2 << endl;
到此這篇關(guān)于C++IO流:fstream, stringstream總結(jié)的文章就介紹到這了,更多相關(guān)C++ fstream, stringstream內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++ std::initializer_list 實(shí)現(xiàn)原理解析及遇到問(wèn)題
這篇文章主要介紹了C++ std::initializer_list 實(shí)現(xiàn)原理勘誤,本文通過(guò)源碼解析給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-02-02C語(yǔ)言入門(mén)篇--函數(shù)及數(shù)組用法
本篇文章是c語(yǔ)言基礎(chǔ)篇,主要為大家介紹了C語(yǔ)言的函數(shù)與數(shù)組,每個(gè)函數(shù)本質(zhì)上都實(shí)現(xiàn)一個(gè)最小的功能,而main函數(shù)只負(fù)責(zé)調(diào)用函數(shù),實(shí)現(xiàn)代碼的核心邏輯,提高代碼的可維護(hù)性2021-08-08C++實(shí)現(xiàn)二叉樹(shù)遍歷序列的求解方法
這篇文章主要介紹了C++實(shí)現(xiàn)二叉樹(shù)遍歷序列的求解方法,需要的朋友可以參考下2014-08-08C語(yǔ)言鏈表實(shí)現(xiàn)學(xué)生信息管理系統(tǒng)程序設(shè)計(jì)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言鏈表實(shí)現(xiàn)學(xué)生信息管理系統(tǒng)程序設(shè)計(jì),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-07-07C語(yǔ)言實(shí)現(xiàn)刪除某一個(gè)數(shù)組值的方法
這篇文章主要給大家分享C語(yǔ)言數(shù)組中刪除數(shù)組中某個(gè)值的方法,既然要學(xué)習(xí)刪除數(shù)組中的元素,我們就必須得先知道數(shù)組中有哪些元素。同時(shí)還要定義一個(gè)變量,并將需要?jiǎng)h除的元素賦值給那個(gè)變量。下面來(lái)看看文章的詳細(xì)內(nèi)容吧2021-11-11