使用 std::cout 添加时间戳

Add time stamp with std::cout

本文关键字:时间戳 添加 cout 使用 std      更新时间:2023-10-16

我有以下代码将我的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以某种方式自动照顾它。这可能吗?

我假设,如果下一行的第一个字符出现在输出中,则您要打印时间戳。获取一个新类并从 std::streambuf 继承它,并以与 filebuf 相同的方式连接它。如果出现换行符字符,请将此事件存储在对象中。出现另一个字符将时间戳添加到流中。

我写了一个使用 RAII 习语来连接流的例子。

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

这是从另一个角度进行的黑客攻击。

运行程序时,将输出通过管道传输到awk,并在那里添加时间戳。命令:

<program> | awk '{print strftime()" "$0}' > logfile

如果您使用的是Windows,则可以从此网站下载gawk。

您可以设置打印时间的格式 strftime 。更多关于这方面的数据可以在手册中找到

你想要这样的东西:

ostream & addTime() {
    std::cout << getTime();
    return std::cout;

并像这样使用它:

addTime() << "printing data" << std::endl;

尝试如下内容(这只是一个摘要,我没有测试它):

class logger : ostream
{
    bool line = true;
public:
    template<typename T> ostream& operator<< (T somedata)
    {
        if (line)
            ostream << getTime();
        ostream << somedata;
        line = somedata == std::endl;
    }
}