Sig*_*ont 5 c++ logging iostream
我有以下代码将我的std::cout输出重定向到日志文件.
std::ofstream out("out.txt");
std::streambuf *coutbuf = std::cout.rdbuf(); //save old buf
std::cout.rdbuf(out.rdbuf()); //redirect std::cout to out.txt!
Run Code Online (Sandbox Code Playgroud)
现在我想要的是,每当发生换行时,当前时间戳将被写入文件.
我知道我可以用以下方法实现:
std::cout << getTime() << "printing data" << std::endl;
Run Code Online (Sandbox Code Playgroud)
但我想要的是以std::cout某种方式自动处理它.那可能吗?
cpp*_*ger 10
我假设,如果下一行的第一个字符出现在输出中,则需要打印TimeStamp.获取一个新类并从std :: streambuf继承它,并以与使用filebuf相同的方式连接它.如果出现换行符,则将此事件存储在对象中.出现另一个字符将时间戳添加到流中.
我写了一个使用RAII习语连接streambuf的例子.
class AddTimeStamp : public std::streambuf
{
public:
AddTimeStamp( std::basic_ios< char >& out )
: out_( out )
, sink_()
, newline_( true )
{
sink_ = out_.rdbuf( this );
assert( sink_ );
}
~AddTimeStamp()
{
out_.rdbuf( sink_ );
}
protected:
int_type overflow( int_type m = traits_type::eof() )
{
if( traits_type::eq_int_type( m, traits_type::eof() ) )
return sink_->pubsync() == -1 ? m: traits_type::not_eof(m);
if( newline_ )
{ // -- add timestamp here
std::ostream str( sink_ );
if( !(str << getTime()) ) // add perhaps a seperator " "
return traits_type::eof(); // Error
}
newline_ = traits_type::to_char_type( m ) == '\n';
return sink_->sputc( m );
}
private:
AddTimeStamp( const AddTimeStamp& );
AddTimeStamp& operator=( const AddTimeStamp& ); // not copyable
// -- Members
std::basic_ios< char >& out_;
std::streambuf* sink_;
bool newline_;
};
Run Code Online (Sandbox Code Playgroud)
以下列方式调用此类的对象:
// some initialisation ..
{
AddTimeStamp ats( cout ); // timestamp is active
// every output to 'cout' will start with a 'getTime()' now
// ...
} // restore the old streambuf in the destructor of AddTimeStamp
Run Code Online (Sandbox Code Playgroud)