Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if a given ostream object has been written to

Can I query an ostream object about whether or not it has been written to? For an ostringstream, one could use

if(!myOssObject.str().empty())

What about the general case, e.g. an ofstream or cout or cerr?

like image 409
Armen Tsirunyan Avatar asked Feb 15 '23 00:02

Armen Tsirunyan


2 Answers

In general No.

You can find out how many char (or something else) is written before flushing (sending out the buffered data) by tellp():

Returns the output position indicator of the current associated streambuf object.

cout << "123";

if (cout.tellp() > 0)
{
    // There is some data written
}

After flushing, these output streams will forget what they've written but the last state flags.

If the output device is a real-time and doesn't buffer anything, tellp can't help.

like image 154
masoud Avatar answered Feb 27 '23 00:02

masoud


It's possible, but only if you can get your hands on the stream beforehand. The only generally guaranteed solution is to insert a filtering streambuf, which keeps track of the number of characters output:

class CountOutput : public std::streambuf
{
    std::streambuf* myDest;
    std::ostream*   myOwner;
    int myCharCount;    //  But a larger type might be necessary

protected:
    virtual int overflow( int ch )
    {
        ++ myCharCount;
        return myDest->sputc( ch );
    }

public:
    CountOutput( std::streambuf* dest )
        : myDest( dest )
        , myOwner( nullptr )
        , myCharCount( 0 )
    {
    }
    CountOutput( std::ostream& dest )
        : myDest( dest.rdbuf() )
        , myOwner( &dest )
        , myCharCount( 0 )
    {
        myOwner->rdbuf( this );
    }
    ~CountOutput()
    {
        if ( myOwner != nullptr ) {
            myOwner.rdbuf( myDest );
        }
    }

    int count() const
    {
        return myCount;
    }
};

As usual, this can be used with just about any std::ostream:

CountOutput counter( someOStream );
//  output counted here...
int outputCount = counter.count();

When it goes out of scope, it will restore the original state of the stream.

like image 33
James Kanze Avatar answered Feb 27 '23 02:02

James Kanze