Using << operator to write to both a file and cout

前端 未结 6 1105
滥情空心
滥情空心 2020-12-02 01:10

I\'d like to overload << operator to write the value it takes to a file and cout. I have tried to do it with following code, but couldn\'t succeed it. It just writes t

6条回答
  •  无人及你
    2020-12-02 01:22

    The usual way of doing this is to use a filtering streambuf, which forwards to both of the target streambufs. Something like the following should do the trick:

    class LoggingStreambuf : public std::streambuf
    {
        std::streambuf* myPrinciple;
        std::ostream*   myOwner;
        std::filebuf    myLogging;
    protected:
        int overflow( int ch ) override
        {
            myLogging->sputc( ch );
            return myPrinciple->sputc( ch );
        }
    public:
        LoggingStreambuf( std::streambuf* principal, std::string const& logFileName )
            : myPrinciple( principal )
            , myOwner( nullptr )
            , myLogging( logFileName )
        {
        }
    
        LoggingStreambuf( std::ostream& principal, std::string const& logFileName )
            : myPrinciple( principal.rdbuf() )
            , myOwner( &principal )
            , myLogging( logFileName )
        {
            myOwner.rdbuf( this );
        }
    
        ~LoggingStreambuf()
        {
            if ( myOwner != nullptr ) {
                myOwner.rdbuf( myPrinciple );
            }
        }
    };
    

    (This particular code supposes that the file output is a log file, a secondary output on which errors should be ignored. Other error handling strategies can also be implemented, and of course, there's no reason that you couldn't provide two arbitrary std::streambuf*, and create a new std::ostream outputting through an instance of the custom streambuf.)

    To use this class, as it is written:

    LoggingStreambuf logger( std::cout, "logfile.txt" );
    //  And output to std::cout as usual...
    

    More generally, of course: anytime you want to do something special with regards to the data sink or source of a stream, you implement a new std::streambuf, since this is the class which handles sinking and sourcing of data for the streams.

提交回复
热议问题