簡而言之,我正在嘗試創建一個鏈接到檔案的流std::ofstream outFile{pathToFile, std::ios_base::app};。該檔案是一個日志檔案,理想情況下,它將接收 stderr 和 stdout 的副本。例如,當發生錯誤時,錯誤將列印在控制臺和檔案中。
我已經嘗試過使用freopen(pathToFile, "a ", stderr);,std::cerr.rdbuf(outFile.rdbuf());但是,這兩個都完全重定向了輸出,類似于 bash 中的管道。我也想在控制臺中看到錯誤。
作為 C 流的新手,我不太確定我將如何實作這一點。我認為它以另一種語言完成的方式是“訂閱”stderr,因此每次 stderr 更改和更新時都會通知我的原始流。另一種方法是覆寫標準錯誤,登錄到我的檔案并呼叫原始檔案,但由于標準錯誤通常不是由程式員本身呼叫的,我不確定如何做到這一點。
應該注意的是,我使用的是 Windows,所以我無法訪問unistd.h. 我也想避免使用STL或第三方庫。
uj5u.com熱心網友回復:
IOStreams 在內部使用 astd::streambuf來實際寫入(或讀取)字符。如果您只想重定向寫入另一個流的所有字符,您可以重定向相應的流緩沖區。不過,您最終應該恢復原始流緩沖區,因為流在??銷毀時會被重繪 ,并且流緩沖區的生命周期很重要。例如
#include <iostream>
#include <fstream>
struct redirect {
std::ostream& d_stream;
std::streambuf* d_orig;
redirect(std::ostream& out, std::ostream& to)
: d_stream(out)
, d_orig(out.rdbuf(to.rdbuf())) {
}
~redirect() { this->d_stream.rdbuf(this->d_orig); }
};
int main() {
std::ofstream log("my-log.txt");
redirect rcout(std::cout, log);
redirect rcerr(std::cerr, log);
std::cout << "hello, ";
std::cerr << "world!\n";
}
如果您還希望重定向的流出現在原始流上,您可以使用“ teestream”,它使用流緩沖區將每個字符復制到兩個不同的流緩沖區(我過去曾在多個地方發布過此類流的多個版本,包括在stackoverflow 上)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/392253.html
上一篇:C 二進制文字
