C++IO流之fstream,?stringstream使用小結
IO流
1. C語言IO
C語言中常用的輸入輸出函數(shù)有如下幾種:前者是格式化標準輸入輸出,后者是格式化文件輸入輸出,最后是格式化字符串輸入輸出。
| 函數(shù)名 | 內(nèi)容 | 備注 |
|---|---|---|
scanf | 從標準輸入流(鍵盤)讀取格式化的數(shù)據(jù) | 省略standard |
fscanf | 從所有輸入流讀取讀取格式化數(shù)據(jù) | f:file |
sscanf | 從字符串中讀取格式化的數(shù)據(jù) | s:string |
printf | 將格式化的數(shù)據(jù)輸出到標準輸出流(屏幕)上 | 省略standard |
fprintf | 將格式化數(shù)據(jù)輸出到所有輸出流上 | f:file |
sprintf | 將格式化的數(shù)據(jù)輸出到字符串中 | s:string |
文件的輸入輸出需要以下幾個函數(shù):
| 函數(shù)名 | 功能 | 適用范圍 |
|---|---|---|
fopen | 打開文件流 | 文件 |
fclose | 關閉文件流 | 文件 |
fscanf | 從所有輸入流讀取讀取格式化數(shù)據(jù) | 文件 |
fprintf | 將格式化數(shù)據(jù)輸出到所有輸出流上 | 文件 |
fread | 二進制輸入 | 文件 |
fwrite | 二進制輸出 | 文件 |
//文件開關 FILE* fopen (const char* filename, const char* mode); int fclose (FILE* stream); //格式化讀寫 int fprintf (FILE* stream, const char* format [, argument ]...); int fscanf (FILE* stream, const char* format [, argument ]...); //二進制讀寫 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語言二進制讀寫
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語言字符讀寫
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++ 標準庫提供了4個全局流對象cin、cout、cerr、clog。cout、cerr、clog 是 ostream 類的三個不同的對象。使用 cout 進行標準輸出,使用 cin 進行標準輸入。同時 C++ 標準庫還提供了 cerr 用來進行標準錯誤的輸出,以及 clog 進行日志的輸出。
2.1 C++標準IO流
cout,cin是ostream,istream類的對象,operator<<,operator>>分別是兩個對象的操作符重載成員函數(shù)。

C++輸出輸入可直接使用cout>>和cin>>,因為其重載了所有內(nèi)置類型,對于自定義類型需要自行重載操作符>>和<<。
cin >> a >> b;
operator<<和operator>>的返回值也是ostream&或istream&,因此支持連續(xù)輸入輸出,又是一次函數(shù)調(diào)用。
cout/cin 取代 printf/scanf 的真正原因是 cout/cin 支持自定義類型,符合面向?qū)ο蟮乃枷搿?/p>
當需要循環(huán)讀入數(shù)據(jù)時,可以采用如下的方式:
string str;
while (cin >> str) {
;
}從文檔中可以看到,operator>>的返回值是istream類型,這個對象類型是如何作真假判斷的呢?
原因是istream類的對象支持一個操作符的重載函數(shù)叫operator bool,C++98中叫operator void*,C++11中叫operator bool。

這是個特殊的運算符重載函數(shù),該函數(shù)不允許限定返回類型,當類型被當作條件判斷時,自動調(diào)用并將返回值強轉為內(nèi)置的標識,該標識如果為真就繼續(xù),如果為假就停止讀取。
2.2 C++文件IO流
采用面向?qū)ο蟮乃枷?,C++中文件指針被文件輸入輸出流對象ofstream、ifstream代替。
和fopen的調(diào)用方式類似,創(chuàng)建輸入輸出流對象,調(diào)用其構造函數(shù)傳入文件地址以及打開模式。fclose被析構函數(shù)代替,且析構函數(shù)可以自動調(diào)用。
| 對象構造函數(shù) | 解釋 |
|---|---|
| ofstream (const char fileName, ios_base::openmode mode=ios_base::out)* | 創(chuàng)建輸出流對象,并指定文件地址和打開模式 |
| ifstream (const char fileName, ios_base::openmode mode=ios_base::in)* | 創(chuàng)建輸入流對象,并指定文件地址 |
打開模式變量的類型是ios_base::openmode,該變量有如下幾個特定的值:
| 模式 | 解釋 |
|---|---|
| in | 文件讀取模式 |
| out | 文件寫入模式 |
| binary | 二進制文件模式 |
| … |
常用的有如上幾種,該變量的值以二進制位中的不同位為1來標識,也就是說使用異或|就可以組合起來用。
| 函數(shù) | 解釋 |
|---|---|
| istream& read(char s, streamsize n);* | read接口是輸入流istream對象的成員函數(shù),參數(shù)是變量和大小。 |
| ostream& write(const char s , streamsize n);* | write接口是輸出流ostream對象的成員函數(shù),參數(shù)是寫入變量和寫入大小。 |
示例
使用一個ConfigManage類來演示幾種文件讀寫的方式。
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)
{}
//二進制寫入
void WriteBin(ServerInfo& info)
{
ofstream ofs(_fileName.c_str(), ios_base::out | ios_base::binary); //創(chuàng)建輸出流對象
ofs.write((const char*)&info, sizeof(ServerInfo)); //調(diào)用write接口
}
//二進制讀取
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;
};
讀寫文件更常用的方式是以文本形式讀寫,因此就可以省略打開模式參數(shù)。
ifstream,ofstream文件輸入輸出類中還繼承了iostream的流插入<<流提取>>操作符,也就是對象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;
}
//文本寫入
void WriteText(ServerInfo& info)
{
ofstream ofs(_fileName.c_str());
//write
ofs.write((const char*)&info, sizeof(ServerInfo));
//1.
ofs << info._ip << info._port; //對象未重載<<
//2.
ofs << info; //對象已重載>>
}
//文本讀取
void ReadText(ServerInfo& info)
{
ifstream ifs(_fileName.c_str());
//read
ifs.read((char*)&info, sizeof(ServerInfo));
//1.
ofs << info._ip << info._port; //對象未重載<<
//2.
ifs >> info; //對象已重載>>
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);
}
文件的輸入輸出流對象調(diào)用構造函數(shù)時也可能會失敗,C++采取面向?qū)ο髵伄惓5男问健?/p>
2.3 C++ stringstream
在頭文件 下,有三個類:istringstream、ostringstream 和 stringstream,分別用來進行字符串流的輸入、輸出和輸入輸出操作。
- 字符串流
ostringstream可以將一個其他類型的數(shù)據(jù)轉化為字符串格式,該類中的成員函數(shù)str可以返回轉出的字符串。 - 字符串流
istringstream可以將一個字符串格式轉化其他類型的數(shù)據(jù),該類中的成員函數(shù)str可以傳入需要轉化的字符串,或直接在構造時傳入。
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; //對象未重載<<
//2.
oss << info1;
string str = oss.str();
cout << str << endl;
//反序列化
PersonInfo info2;
istringstream iss(str);
iss.str(str);
//1.
iss >> info2._name >> info2._age; //對象未重載>>
//2.
iss >> info2;
cout << info2 << endl;
到此這篇關于C++IO流:fstream, stringstream總結的文章就介紹到這了,更多相關C++ fstream, stringstream內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
C++類與對象深入之引用與內(nèi)聯(lián)函數(shù)與auto關鍵字及for循環(huán)詳解
朋友們好,這篇播客我們繼續(xù)C++的初階學習,現(xiàn)在對一些C++的入門知識做了些總結,整理出來一篇博客供我們一起復習和學習,如果文章中有理解不當?shù)牡胤?還希望朋友們在評論區(qū)指出,我們相互學習,共同進步2022-06-06
C語言中帶頭雙向循環(huán)鏈表基本操作的實現(xiàn)詳解
無頭單向非循環(huán)鏈表結構簡單,一般不會單獨用來存數(shù)據(jù)。而帶頭雙向循環(huán)鏈表的結構較為復雜,一般用在單獨存儲數(shù)據(jù)。本文將介紹帶頭雙向循環(huán)鏈表的基本操作,需要的可以參考一下2022-11-11
linux下c語言中隱藏進程命令行參數(shù)(例如輸入密碼等高危操作)
啟動程序很多時候用命令行參數(shù)可以很方便,做到簡化一些配置,但是輸入用戶名密碼等操作,如果通過進程查看工具直接看到密碼就太不安全了,這里就為大家分享一下方法2021-01-01

