?基本概念
程序運行時產生的數據都屬于臨時數據,程序一旦運行結束都會被釋放
通過文件可以將數據持久化
C++中對文件操作需要包含頭文件 <fstream>
文件類型分為兩種:
- 文本文件 - 文件以文本的ASCII碼形式存儲在計算機中
- 二進制文件 - 文件以文本的二進制形式存儲在計算機中,用戶一般不能直接讀懂它們
操作文件的三大類:
????????1. ofstream:寫操作
????????2. ifstream:讀操作
????????3. fstream:讀寫操作
#include <fstream> // 必須包含的頭文件
數據特性 | 說明 |
---|---|
程序運行時數據 | 臨時數據,程序結束即釋放 |
文件持久化數據 | 長期存儲在磁盤中 |
文件打開模式
模式標志 | 功能描述 |
---|---|
ios::in | 為讀取打開文件 |
ios::out | 為寫入打開文件 |
ios::ate | 初始定位到文件末尾 |
ios::app | 追加寫入模式 |
ios::trunc | 存在則清空重建 |
ios::binary | 二進制模式操作 |
文本文件
寫文件
void test01() {// 1. 包含頭文件(已在全局包含)// 2. 創建輸出流對象ofstream ofs;// 3. 指定打開方式(組合模式用 | 連接)ofs.open("test.txt", ios::out | ios::trunc);// 4. 寫入格式化數據ofs << "姓名:張三" << endl; // 正確使用<<運算符ofs << "性別:男" << endl;ofs << "年齡:18" << endl;// 5. 關閉文件流ofs.close();
}
讀文件
基礎操作框架
#include <fstream> // 必須包含的頭文件
#include <string> // 字符串操作支持void readFileDemo() {// 1. 創建流對象ifstream ifs;// 2. 打開文件并驗證ifs.open("test.txt", ios::in); // ios::in表示讀取模式if (!ifs.is_open()) { // 必須檢查打開狀態cerr << "文件打開失敗" << endl;return;}// 3. 讀取數據(四種方式見下文)// 4. 關閉文件流ifs.close();
}
四種讀取方式對比
方式1:運算符重載讀取
char buf[1024] = {0}; // 1024為緩沖區長度
while (ifs >> buf) { // 自動處理空格/換行分隔cout << buf << endl;
}
特點:
- 自動按空白符分割內容
- 緩沖區需預分配固定大小
- 適合結構化數據讀取
方式2:getline成員函數
char buf[1024] = {0};
while (ifs.getline(buf, sizeof(buf))) { // 流對象的成員函數cout << buf << endl; // 自動處理換行符
}
特點:
- 精確控制緩沖區大小
- 自動去除換行符
- 需注意緩沖區溢出風險
方式3:全局getline函數
string buf;
while (getline(ifs, buf)) { // 使用string自動管理內存cout << buf << endl; // 無長度限制
}
特點:
- 自動管理內存
- 無需擔心緩沖區溢出
- 標準推薦方式
方式4:逐字符讀取
char c;
while ((c = ifs.get()) != EOF) { // EOF檢測cout << c; // 原樣輸出所有字符
}
特點:
- 完全控制讀取過程
- 適合二進制文件處理
- 性能開銷較大
二進制文件
核心操作框架
#include <fstream>
#include <string>// 示例數據結構
struct PlayerData {int id; // 4字節double score; // 8字節char name[32]; // 32字節
}; // 總大小:44字節void binaryDemo() {// 創建流對象fstream file("game.dat", ios::binary | ios::out | ios::in);// 驗證文件狀態if (!file.is_open()) {cerr << "文件打開失敗" << endl;return;}// 讀寫操作(見下文示例)file.close();
}
讀寫文件
// 讀取基本類型
int loadedScore;
file.read(reinterpret_cast<char*>(&loadedScore), sizeof(int));// 讀取結構體(需內存對齊)
#pragma pack(push, 1) // 1字節對齊
struct PackedData {short type;bool valid;// ...
};
#pragma pack(pop)PackedData data;
file.read(reinterpret_cast<char*>(&data), sizeof(PackedData));// 批量讀取
vector<PlayerData> players(10);
file.read(reinterpret_cast<char*>(players.data()), players.size() * sizeof(PlayerData));