我有以下代码将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!
现在我想要的是,每当发生换行时,当前的时间戳将被写入文件。
我知道我可以用以下方式实现:
std::cout << getTime() << "printing data" << std::endl;
但我想要的是std::cout
以某种方式自动处理它。这可能吗?
答案 0 :(得分:9)
我假设,如果下一行的第一个字符出现在输出中,则需要打印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_;
};
按以下方式调用此类的对象:
// 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
答案 1 :(得分:2)
这是一个不同点的黑客攻击。
运行程序时,将输出通过管道传输到awk,并在其中添加时间戳。命令:
<program> | awk '{print strftime()" "$0}' > logfile
如果您使用的是Windows,可以从this website下载gawk。
您可以格式化strftime
打印的时间。有关该数据的更多数据可以在in the manual
答案 2 :(得分:0)
你想要这样的东西:
ostream & addTime() {
std::cout << getTime();
return std::cout;
并像这样使用它:
addTime() << "printing data" << std::endl;
答案 3 :(得分:0)
class logger : ostream
{
bool line = true;
public:
template<typename T> ostream& operator<< (T somedata)
{
if (line)
ostream << getTime();
ostream << somedata;
line = somedata == std::endl;
}
}