一種解決方案是將寫入cerr的所有內容複製到例如文件中。
這是輔助類:
class CTee {
public:
// Use ostream &s2 if you want to duplicate to an ostream, pass other
// stuff you need if you have other logging mechanisms.
CTee(ostream &s1, ostream &s2) : m_s1(s1), m_s1OrigBuf(s1.rdbuf()), m_teebuf(s1.rdbuf(), s2.rdbuf()) { s1.rdbuf(&m_teebuf); }
~CTee() { m_s1.rdbuf(m_s1OrigBuf); }
private:
CTee &operator =(CTee &rhs); // not implemented
class CTeeBuf : public streambuf {
public:
// Use streambuf *sb2 if you want to duplicate to an ostream/streambuf.
// Pass other Information if you want to log to something different.
CTeeBuf(streambuf* sb1, streambuf* sb2) : m_sb1(sb1), m_sb2(sb2) {}
protected:
virtual int_type overflow(int_type c) {
if(streambuf::traits_type::eq_int_type(c, streambuf::traits_type::eof()))
return c;
else {
// Put char to cerr/stream to duplicate
m_sb1->sputc((streambuf::char_type)c);
// Put char to duplicate stream. If you want to duplicate to something
// different, then write the char whereever you want to.
return m_sb2->sputc((streambuf::char_type)c);
}
}
virtual int sync() {
m_sb1->pubsync();
return m_sb2->pubsync();
}
// Store streambuf *m_sb2 if you want to duplicate to streambuf.
// Store anything else if you want to duplicate to something different.
streambuf *m_sb1, *m_sb2;
};
ostream &m_s1;
streambuf * const m_s1OrigBuf;
CTeeBuf m_teebuf;
};
CTee需要一個ostream
複製和ostream
複製到。它需要重複的ostream,並用CTeeBuf(見CTee ctor)替換它寫入的rdbuf
,streambuf
。 CTeeBuf獲取寫入它的char
,並將它們轉發給ostream
s(請參閱CTeeBuf :: overflow和CTeeBuf :: sync)的streambuf
。 CTee dtor將已更改的streambuf
恢復爲其原始值。
而且它使用的是這樣的:
char logfilename[] = "myfile.log";
ofstream logfile(logfilename, ios_base::out | ios_base::app);
CTee tee(cerr, logfile);
從現在開始,一切都寫入CERR將被複制(三通的壽命期間)到日誌文件。因此,此消息將被寫入CERR,也記錄到logfile:
cerr << "error occured: ..." << endl;
也可以寫信給其他ostreams比日誌文件。如果你不想複製到另一個ostream
而只是其他的東西,只需用一個實現來替換CTeeBuf :: overflow即可。請參閱http://www.cs.technion.ac.il/~imaman/programs/teestream.html和http://wordaligned.org/articles/cpp-streambufs。
@BenjaminBannier:關閉不夠的 - 有答案存在不依賴於'.rdbuf'背後'cout'。 – MSalters
你正在參考的答案不回答我的問題,它使用醜陋的鏈接黑客。我正在尋找一種通過代碼實現的方法。 – OopsUser
鏈接問題中有多個答案。我會同意鏈接攻擊是醜陋的,但是有時候會出現醜陋的解決方案:在沒有非醜陋的解決方案時。 – MSalters