首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C++ IO 庫全景解析:流體系架構、狀態控制與最佳實踐

     編輯:關於C++

前言

C++ IO 庫分為「基於流的 IO」與「C 風格 IO 函數」兩大體系。本文聚焦現代 C++ 核心——iostream 流庫,深度解析類繼承體系、類型別名、條件狀態機制、緩衝區控制、文件/字符串流實戰,助你構建健壯、高效的 IO 代碼。

一、流類繼承體系與類型別名

1. 核心繼承關係

ios_base (接口層:格式旗標、異常掩碼)
    ↑
basic_ios (基類:流狀態、緩衝區指針、tie、rdbuf)
    ↑
basic_streambuf (緩衝區抽象:內存/文件/字符串)
    ↑
basic_istream / basic_ostream / basic_iostream (輸入/輸出/雙向流)
    ↑
basic_ifstream / basic_ofstream / basic_fstream (文件流)
basic_istringstream / basic_ostringstream / basic_stringstream (字符串流)

2. 標準類型別名 (<ios>, <streambuf>, <istream>, <ostream>, <fstream>, <sstream>)

窄字符寬字符說明
ioswiosbasic_ios 別名
streambufwstreambufbasic_streambuf 別名
filebufwfilebufbasic_filebuf 別名
stringbufwstringbufbasic_stringbuf 別名
istreamwistreambasic_istream 別名
ostreamwostreambasic_ostream 別名
iostreamwiostreambasic_iostream 別名
ifstreamwifstreambasic_ifstream 別名
ofstreamwofstreambasic_ofstream 別名
fstreamwfstreambasic_fstream 別名
istringstreamwistringstreambasic_istringstream 別名
ostringstreamwostringstreambasic_ostringstream 別名
stringstreamwstringstreambasic_stringstream 別名

3. 預定義標準流對象

  • cin / wcin:標準輸入流(關聯 stdin)
  • cout / wcout:標準輸出流(關聯 stdout,默認行緩衝/全緩衝)
  • cerr / wcerr:標準錯誤流(無緩衝,立即刷新)
  • clog / wclog:標準日誌流(全緩衝)

可通過 rdbuf() 重定向緩衝區,改變流行為(如將 cout 導向文件)。

二、流條件狀態機制

1. 四大狀態旗標

旗標含義對應查詢函數
goodbit流正常,無錯誤good()
eofbit到達文件/流末尾eof()
failbit操作失敗(如格式錯誤),可恢復fail()
badbit流損壞(如硬件故障),不可恢復bad()

2. 狀態操作函數


rdstate()          // 獲取當前狀態位掩碼
setstate(flags)    // 設置狀態位(或運算)
clear(flags=goodbit) // 重置狀態,默認清除所有錯誤位
exceptions(mask)   // 設置哪些狀態位觸發異常拋出

3. 實戰:狀態控制與錯誤恢復

#include 
#include 
#include 
using namespace std;

int main() {
    string obj = "just a test!";
    stringstream ss(obj);
    
    // 手動設置 failbit 模拟錯誤
    auto state = ss.rdstate();
    ss.setstate(state | stringstream::failbit);
    
    string tmp;
    while (ss >> tmp) { // 因 failbit 設置,循環不會執行
        cout << tmp << endl;
    }
    
    cout << "fail() = " << ss.fail() << endl; // 1 (true)
    
    // 恢復流狀態
    ss.clear(); // 清除所有錯誤位
    ss.seekg(0); // 重置讀取位置
    
    while (ss >> tmp) {
        cout << tmp << endl; // 正常輸出: just / a / test!
    }
    return 0;
}

4. 狀態位與查詢函數對應表

查詢函數返回 true 的條件
good()rdstate() == goodbit
eof()(rdstate() & eofbit) != 0
fail()(rdstate() & (failbit | badbit)) != 0
bad()(rdstate() & badbit) != 0

三、格式化控制


// 基數
cout << hex << 255 << endl;  // ff
cout << dec << 255 << endl;  // 255

// 浮點精度與格式
cout << fixed << setprecision(2) << 3.14159 << endl; // 3.14
cout << scientific << 1000.0 << endl; // 1.00e+03

// 寬度、填充、對齊
cout << setw(10) << setfill('*') << left << "hello" << endl; // hello*****

// 布爾值輸出 true/false
cout << boolalpha << true << endl; // true

四、文件流 (<fstream>) 實戰

1. 基本打開模式

模式旗標含義
ios::in讀取
ios::out寫入(默認截斷文件)
ios::app追加寫入(保留原內容)
ios::ate打開後定位到文件末尾
ios::trunc截斷文件(默認)
ios::binary二進制模式(無換行符轉換)

2. 完整讀寫示例

#include 
#include 
#include 

void write_file() {
    ofstream ofs("data.txt", ios::out | ios::trunc);
    if (!ofs) { cerr << "open failed\n"; return; }
    ofs << "Line 1\n" << "Line 2\n";
    ofs.close(); // RAII 析構自動關閉,手動 close 可提前檢查錯誤
}

void read_file() {
    ifstream ifs("data.txt", ios::in);
    if (!ifs) { cerr << "open failed\n"; return; }
    
    string line;
    while (getline(ifs, line)) { // 按行讀取,不包含換行符
        cout << line << endl;
    }
    
    // 二進制讀取
    ifstream bin("data.bin", ios::in | ios::binary);
    bin.seekg(0, ios::end);
    size_t size = bin.tellg();
    bin.seekg(0, ios::beg);
    vector buffer(size);
    bin.read(buffer.data(), size);
}

五、字符串流 (<sstream>) 實戰

#include 
#include 
#include 

void parse_csv_line(const string& line) {
    stringstream ss(line);
    string field;
    vector fields;
    while (getline(ss, field, ',')) { // 指定分隔符
        fields.push_back(field);
    }
    // fields 現包含所有欄位
}

string format_output(int id, double score) {
    ostringstream oss;
    oss << "ID:" << id << " Score:" << fixed << setprecision(1) << score;
    return oss.str(); // 獲取格式化字符串
}

六、C 風格 IO (<cstdio>) 互操作

  • std::ios::sync_with_stdio(false):關閉 C/C++ 流同步,**大幅提升 IO 性能**(競程必開)。
  • cin.tie(nullptr):解除 cin 與 cout 綁定,進一步加速(無需交互提示時)。
  • 混用時注意:關閉同步後,**不能**混用 printf/scanf 與 cout/cin,行為未定義。

七、最佳實踐清單

  1. 優先使用 iostream,類型安全、可擴展、支援自定義類型重載 operator<</>>。
  2. 讀取前檢查流狀態:if (cin >> x) 隱式轉換為 bool 等價於 !cin.fail()。
  3. 大量數據讀寫:關閉同步 ios::sync_with_stdio(false); cin.tie(nullptr);。
  4. 文件流利用 RAII,避免手動 close(),析構自動刷新並關閉。
  5. 二進制數據務必加 ios::binary,避免 Windows 下 \n↔\r\n 轉換損壞數據。
  6. 異常安全:設置 exceptions(failbit | badbit) 讓流錯誤拋出異常,配合 RAII 實現自動清理。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved