Add time stamp with std::cout

2019-01-18 07:27发布

I have the following code which is redirecting my std::cout output to a log file.

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!

Now what I want is that whenever a newline is occurring, then the current time stamp will be written to the file.

I know I can achive this with:

std::cout << getTime() << "printing data" << std::endl;

But what I want is that of std::cout taking care of it automatically somehow. Is that possible?

4条回答
SAY GOODBYE
2楼-- · 2019-01-18 07:34

That's a hack from a different point.

When you run the program, pipe the output into awk, and add there the time stamp. The command:

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

If you are using windows, you can download gawk from this website.

You can format the time printed by strftime. More data on that can be found in the manual

查看更多
beautiful°
3楼-- · 2019-01-18 07:34

try something like the following (it's just an abstract, I didn't test it):

class logger : ostream
{
    bool line = true;
public:
    template<typename T> ostream& operator<< (T somedata)
    {
        if (line)
            ostream << getTime();
        ostream << somedata;
        line = somedata == std::endl;
    }
}
查看更多
Ridiculous、
4楼-- · 2019-01-18 07:45

You want something like:

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

and use it like this:

addTime() << "printing data" << std::endl;
查看更多
闹够了就滚
5楼-- · 2019-01-18 07:47

I assume, that You want print the TimeStamp, if the first character of the next line appears in the output. Take a new class and inherit it from std::streambuf and connect it in the same way You do with the filebuf. If a newline-charater appears store this event in the object. Appears another character add the timestamp to the stream.

I wrote an example which use the RAII idiom for connecting the 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_;
};

call an object of this class in following way:

// 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
查看更多
登录 后发表回答