一种解决方案是将写入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