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

C++ streambuf 重導向輸出流實戰範例

     編輯:關於C++

核心技巧

std::streambuf 是 C++ I/O 流的底層緩衝區介面。透過 rdbuf() 交換緩衝區指標,即可在不修改上層邏輯下實現輸出流重導向。

經典範例:將 cout 導向檔案

#include <iostream>
#include <fstream>

int main() {
    std::ofstream log("out.log");
    // 保存原始緩衝區,將 cout 綁定至 log
    std::streambuf* backup = std::cout.rdbuf(log.rdbuf());

    std::cout << "Test\n";   // 寫入 out.log

    // 還原 cout
    std::cout.rdbuf(backup);
    std::cout << "Test2\n";  // 寫入螢幕

    return 0;
}

關鍵點解析

  1. rdbuf(new_buf) 回傳舊緩衝區指標,必須保存以便還原。
  2. 此法適用於所有繼承自 std::ios 的流(cin、cerr、clog、stringstream 等)。
  3. 執行緒不安全:多執行緒同時交換同一流的緩衝區會導致競態,需外部同步。

進階應用場景

  • 單元測試捕獲輸出:重導向 cout 至 ostringstream,驗證程式輸出內容。
  • 日誌系統無侵入式整合:第三方庫直接用 cout,主程式啟動時重導向至日誌檔/系統日誌。
  • 雙重輸出:自訂 teebuf 繼承 streambuf,overflow() 同時寫入兩個目標緩衝區,實現「螢幕+檔案」同步輸出。

自訂 TeeBuf 範例草圖

class teebuf : public std::streambuf {
    std::streambuf* buf1;
    std::streambuf* buf2;
protected:
    int overflow(int c) override {
        if (c == EOF) return EOF;
        int r1 = buf1->sputc(c);
        int r2 = buf2->sputc(c);
        return (r1 == EOF || r2 == EOF) ? EOF : c;
    }
    std::streamsize xsputn(const char* s, std::streamsize n) override {
        return std::min(buf1->sputn(s, n), buf2->sputn(s, n));
    }
public:
    teebuf(std::streambuf* b1, std::streambuf* b2) : buf1(b1), buf2(b2) {}
};

// 使用
std::ofstream log("app.log");
teebuf tee(std::cout.rdbuf(), log.rdbuf());
std::cout.rdbuf(&tee);  // 之後所有 cout 同時輸出螢幕與檔案
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved