<fstream>#include
#include
#include
int main() {
const char* filename = "mytext.txt";
// 寫入
{
std::ofstream ofs(filename);
if (!ofs) { std::cerr << "Open for write failed\n"; return 1; }
for (int i = 1; i <= 10; ++i)
ofs << "第" << i << "行\n";
} // RAII 自動 close
// 讀取 —— 正確姿勢
{
std::ifstream ifs(filename);
if (!ifs) { std::cerr << "Open for read failed\n"; return 1; }
std::string line;
while (std::getline(ifs, line)) { // 按行讀取,自動處理換行
std::cout << line << '\n';
}
}
// 讀取 —— 錯誤姿勢(>> 操作符按空白分割)
{
std::ifstream ifs(filename);
std::string word;
while (ifs >> word) { // 遇到空白/換行分割,非按行!
std::cout << word << '\n';
}
}
}
while (ifs.good()) ifs >> word; 導致末行重複// 錯誤代碼
std::ifstream ifs(filename);
std::string word;
while (ifs.good()) { // 讀取失敗後 good() 仍為 true,進入循環
ifs >> word; // 讀取失敗,word 保持上次值
std::cout << word << '\n'; // 打印上次值 → 末行重複
}
原因:good() 在讀取操作**之前**檢查狀態。讀到 EOF 時,提取失敗,但 good() 尚未更新為 false,導致多執行一次循環體。
| 需求 | 正確寫法 |
|---|---|
| 按行讀取(保留換行結構) | while (std::getline(ifs, line)) |
| 按詞讀取(空白分隔) | while (ifs >> word) |
| 按字符讀取 | while (ifs.get(ch)) |
| 二進制塊讀取 | ifs.read(buf, size) 搭配 ifs.gcount() |
**核心原則**:將讀取操作作為循環條件,流對象隱式轉換為 bool 表示「上次操作成功」。
std::ofstream ofs("file", std::ios::out | std::ios::app | std::ios::binary);
// out: 輸出 | app: 追加 | binary: 二進制(無換行轉換)
std::ifstream ifs("file", std::ios::in | std::ios::binary);
ifs.fail():邏輯錯誤(如格式不匹配);ifs.bad():系統級錯誤(磁盤故障);ifs.eof():到達文件末尾;ifs.clear():重置狀態旗標(慎用)。std::fstream 配合 RAII、getline/operator>> 循環條件判斷,是 C++ 文本文件處理的標準、安全、高效方式。**拒絕 good() 循環,擁抱「讀取即判斷」模式**,即可避開末行重複、EOF 誤判等經典坑。