日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

C++IO流之fstream,?stringstream使用小結_C 語言

作者:AKA你的閨蜜 ? 更新時間: 2022-06-13 編程語言

IO流

1. C語言IO

C語言中常用的輸入輸出函數有如下幾種:前者是格式化標準輸入輸出,后者是格式化文件輸入輸出,最后是格式化字符串輸入輸出。

函數名 內容 備注
scanf 標準輸入流(鍵盤)讀取格式化的數據 省略standard
fscanf 所有輸入流讀取讀取格式化數據 f:file
sscanf 字符串中讀取格式化的數據 s:string
printf 將格式化的數據輸出到標準輸出流(屏幕)上 省略standard
fprintf 將格式化數據輸出到所有輸出流 f:file
sprintf 將格式化的數據輸出到字符串 s:string

文件的輸入輸出需要以下幾個函數:

函數名 功能 適用范圍
fopen 打開文件流 文件
fclose 關閉文件流 文件
fscanf 所有輸入流讀取讀取格式化數據 文件
fprintf 將格式化數據輸出到所有輸出流 文件
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、coutcerr、clog。cout、cerr、clog 是 ostream 類的三個不同的對象。使用 cout 進行標準輸出,使用 cin 進行標準輸入。同時 C++ 標準庫還提供了 cerr 用來進行標準錯誤的輸出,以及 clog 進行日志的輸出。

2.1 C++標準IO流

cout,cinostream,istream類的對象,operator<<,operator>>分別是兩個對象的操作符重載成員函數。

C++輸出輸入可直接使用cout>>cin>>,因為其重載了所有內置類型,對于自定義類型需要自行重載操作符>><<。

cin >> a >> b;

operator<<operator>>的返回值也是ostream&istream&,因此支持連續輸入輸出,又是一次函數調用。

cout/cin 取代 printf/scanf 的真正原因是 cout/cin 支持自定義類型,符合面向對象的思想。

當需要循環讀入數據時,可以采用如下的方式:

string str;
while (cin >> str) {
	;
}

從文檔中可以看到,operator>>的返回值是istream類型,這個對象類型是如何作真假判斷的呢?

原因是istream類的對象支持一個操作符的重載函數叫operator bool,C++98中叫operator void*,C++11中叫operator bool

這是個特殊的運算符重載函數,該函數不允許限定返回類型,當類型被當作條件判斷時,自動調用并將返回值強轉為內置的標識,該標識如果為真就繼續,如果為假就停止讀取。

2.2 C++文件IO流

采用面向對象的思想,C++中文件指針被文件輸入輸出流對象ofstream、ifstream代替。

fopen的調用方式類似,創建輸入輸出流對象,調用其構造函數傳入文件地址以及打開模式。fclose被析構函數代替,且析構函數可以自動調用。

對象構造函數 解釋
ofstream (const char fileName, ios_base::openmode mode=ios_base::out)* 創建輸出流對象,并指定文件地址和打開模式
ifstream (const char fileName, ios_base::openmode mode=ios_base::in)* 創建輸入流對象,并指定文件地址

打開模式變量的類型是ios_base::openmode,該變量有如下幾個特定的值:

模式 解釋
in 文件讀取模式
out 文件寫入模式
binary 二進制文件模式
?

常用的有如上幾種,該變量的值以二進制位中的不同位為1來標識,也就是說使用異或|就可以組合起來用。

函數 解釋
istream& read(char s, streamsize n);* read接口是輸入流istream對象的成員函數,參數是變量和大小。
ostream& write(const char s , streamsize n);* write接口是輸出流ostream對象的成員函數,參數是寫入變量和寫入大小。

示例

使用一個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); //創建輸出流對象
		ofs.write((const char*)&info, sizeof(ServerInfo)); //調用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;
};

讀寫文件更常用的方式是以文本形式讀寫,因此就可以省略打開模式參數。

ifstream,ofstream文件輸入輸出類中還繼承了iostream的流插入<<流提取>>操作符,也就是對象ofsifs也可以使用<<>>操作符。

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;
}

具體調用方式則是如下:

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);
}

文件的輸入輸出流對象調用構造函數時也可能會失敗,C++采取面向對象拋異常的形式。

2.3 C++ stringstream

在頭文件 下,有三個類:istringstream、ostringstream 和 stringstream,分別用來進行字符串流的輸入、輸出和輸入輸出操作。

  • 字符串流ostringstream可以將一個其他類型的數據轉化為字符串格式,該類中的成員函數str可以返回轉出的字符串。
  • 字符串流istringstream可以將一個字符串格式轉化其他類型的數據,該類中的成員函數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;

原文鏈接:https://blog.csdn.net/yourfriendyo/article/details/124061797

欄目分類
最近更新