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;
}
rdbuf(new_buf) 回傳舊緩衝區指標,必須保存以便還原。std::ios 的流(cin、cerr、clog、stringstream 等)。cout 至 ostringstream,驗證程式輸出內容。cout,主程式啟動時重導向至日誌檔/系統日誌。teebuf 繼承 streambuf,overflow() 同時寫入兩個目標緩衝區,實現「螢幕+檔案」同步輸出。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 同時輸出螢幕與檔案