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

C++ iostreams 緩衝區深度解析:streambuf、get/put 指標與 rdbuf() 實戰應用

     編輯:關於C++

C++ iostreams 以 streambuf 抽象緩衝區操作。本文深入解析緩衝區架構、雙指標機制、rdbuf() 進階用法與定位操作。

緩衝區核心架構

  • 每個 stream 物件包含 streambuf* 指標,指向衍生自 basic_streambuf<CharT, Traits> 的緩衝區物件。
  • rdbuf() 返回該指標,允許直接操作緩衝區。
  • 緩衝區維護兩個獨立指標:
    • get pointer (gptr):下一個待讀取字元位置
    • put pointer (pptr):下一個待寫入字元位置

rdbuf() 直接輸出整個緩衝區

std::ifstream fin("1.txt");
std::cout << fin.rdbuf() << std::endl;  // 一次性輸出檔案全部內容

運作機制:operator<<(streambuf*) 從緩衝區 gptr 讀取至 EOF。

緩衝區狀態與指標互動

std::ifstream fin("1.txt");
std::string str;
fin >> str;              // 提取第一個詞,gptr 前進
std::cout << fin.rdbuf(); // 輸出「剩餘」內容(gptr 之後)

定位操作:seekg/seekp 與 tellg/tellp

函式適用流向操作目標參考點
seekg(pos)輸入get pointerbeg/cur/end
seekp(pos)輸出put pointerbeg/cur/end
tellg()輸入回傳 get pointer 位置 (streampos)-
tellp()輸出回傳 put pointer 位置 (streampos)-

範例:記錄並還原讀取位置

std::ifstream fin("1.txt");
std::streampos pos = fin.tellg();  // 記錄初始位置 (0)
std::string word;
fin >> word;                       // 讀取第一個詞
fin.seekg(pos);                    // 回到開頭
std::cout << fin.rdbuf();          // 重新輸出完整檔案

完整追蹤示範

#define PRINTCURPOS(in) std::cout << "cur pos: " << in.tellg() << std::endl
#define PRINTANDEXEC(st) std::cout << #st << std::endl; st

int main() {
    PRINTANDEXEC(std::ifstream fin("1.txt"));
    PRINTANDEXEC(std::string str);
    PRINTCURPOS(fin);                    // 0
    PRINTANDEXEC(fin >> str);           // 讀取 "hello"
    PRINTCURPOS(fin);                    // 6 (含空白)
    PRINTANDEXEC(fin.seekg(2, std::ios::beg));
    PRINTCURPOS(fin);                    // 2
    PRINTANDEXEC(std::cout << fin.rdbuf() << std::endl);  // 從位置2輸出
    PRINTCURPOS(fin);                    // 檔案末尾
}

自訂 streambuf 實作要點

  • 繼承 std::streambuf,覆寫虛函式:
    • underflow():輸入緩衝區空時填充資料
    • overflow():輸出緩衝區滿時排洩資料
    • sync():同步緩衝區至外部裝置
    • seekoff()/seekpos():支援定位
  • 使用 setg()、setp() 設定內部緩衝區指標(eback/gptr/egptr、pbase/pptr/epptr)。

常見誤區

  1. rdbuf() 輸出**不保證**為完整檔案內容,取決於當前 gptr 位置。
  2. seekg 僅對輸入流有效,ofstream 無此函式;seekp 僅對輸出流有效。
  3. tellg/tellp 回傳 streampos(實作為 fpos<mbstate_t>),不可直接當整數運算,需轉換。
  4. 雙向流 fstream 擁有獨立 get/put 指標,互不影響。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved