Re: How to redirect clog to cout and ofstream at the same time?

Discussion in 'C++' started by ksamdev, Sep 10, 2010.

  1. ksamdev

    ksamdev Guest

    On Sep 10, 11:34 am, "Johannes Schaub (litb)" <>
    wrote:
    > ksamdev wrote:
    > > Hi,

    >
    > > Is is possible to make clog output messages into two output stream
    > > simultaneously, say: cout and ostream?

    >
    > > Unfortunately, ostream::rdbuf(...) allows to set only one at a time.

    >
    > > I'd like to have messages that are sent to clog to be output on the
    > > screen and logged in file at the same time.

    >
    > "ostream"? That's the class type of cout, not an object's stream. You can
    > write a rdbuf that writes into two different buffers like
    >
    > struct mybuf : streambuf {
    >   mybuf(streambuf *a, streambuf *b)
    >    :a(a),b(b)
    >   { }
    >
    > protected:
    >   int overflow(int c) {
    >     if(a->sputc(c) == EOF) return EOF;
    >     if(b->sputc(c) == EOF) return EOF;
    >     return c;
    >   }  
    > private:
    >   streambuf *a, *b;
    >
    > };
    >
    > You can then connect like the following, remembering to later restore clog.
    >
    >     filebuf fb;
    >     fb.open(...);
    >
    >     mybuf m(cout.rdbuf(), &fb);
    >     streambuf *b = clog.rdbuf(&m);
    >     clog << "i go into cout and into the file!";
    >     clog.rdbuf(b);


    Thanks for the advice.

    In the original email I was talking about any ostream other than cout:
    it might be ofstream, cerr, osstringstream, etc.

    Does your code work with <iomanip> (manipulators) ?
     
    ksamdev, Sep 10, 2010
    #1
    1. Advertising

  2. ksamdev

    James Kanze Guest

    On Sep 10, 5:45 pm, ksamdev <> wrote:
    > On Sep 10, 11:34 am, "Johannes Schaub (litb)" <>
    > wrote:
    > > ksamdev wrote:


    > > > Is is possible to make clog output messages into two
    > > > output stream simultaneously, say: cout and ostream?


    > > > Unfortunately, ostream::rdbuf(...) allows to set only one at a time.


    > > > I'd like to have messages that are sent to clog to be output on the
    > > > screen and logged in file at the same time.


    > > "ostream"? That's the class type of cout, not an object's stream. You can
    > > write a rdbuf that writes into two different buffers like


    > > struct mybuf : streambuf {
    > > mybuf(streambuf *a, streambuf *b)
    > > :a(a),b(b)
    > > { }


    > > protected:
    > > int overflow(int c) {
    > > if(a->sputc(c) == EOF) return EOF;
    > > if(b->sputc(c) == EOF) return EOF;
    > > return c;
    > > }
    > > private:
    > > streambuf *a, *b;
    > > };


    > > You can then connect like the following, remembering to later restore clog.


    > > filebuf fb;
    > > fb.open(...);

    >
    > > mybuf m(cout.rdbuf(), &fb);
    > > streambuf *b = clog.rdbuf(&m);
    > > clog << "i go into cout and into the file!";
    > > clog.rdbuf(b);


    > Thanks for the advice.


    > In the original email I was talking about any ostream other
    > than cout: it might be ofstream, cerr, osstringstream, etc.


    > Does your code work with <iomanip> (manipulators) ?


    What do manipulators have to do with streambuf?

    --
    James Kanze
     
    James Kanze, Sep 10, 2010
    #2
    1. Advertising

  3. ksamdev

    ksamdev Guest

    On Sep 10, 1:26 pm, James Kanze <> wrote:
    > On Sep 10, 5:45 pm, ksamdev <> wrote:
    >
    >
    >
    >
    >
    > > On Sep 10, 11:34 am, "Johannes Schaub (litb)" <>
    > > wrote:
    > > > ksamdev wrote:
    > > > > Is is possible to make clog output messages into two
    > > > > output stream simultaneously, say: cout and ostream?
    > > > > Unfortunately, ostream::rdbuf(...) allows to set only one at a time..
    > > > > I'd like to have messages that are sent to clog to be output on the
    > > > > screen and logged in file at the same time.
    > > > "ostream"? That's the class type of cout, not an object's stream. You can
    > > > write a rdbuf that writes into two different buffers like
    > > > struct mybuf : streambuf {
    > > >   mybuf(streambuf *a, streambuf *b)
    > > >    :a(a),b(b)
    > > >   { }
    > > > protected:
    > > >   int overflow(int c) {
    > > >     if(a->sputc(c) == EOF) return EOF;
    > > >     if(b->sputc(c) == EOF) return EOF;
    > > >     return c;
    > > >   }
    > > > private:
    > > >   streambuf *a, *b;
    > > > };
    > > > You can then connect like the following, remembering to later restore clog.
    > > >     filebuf fb;
    > > >     fb.open(...);

    >
    > > >     mybuf m(cout.rdbuf(), &fb);
    > > >     streambuf *b = clog.rdbuf(&m);
    > > >     clog << "i go into cout and into the file!";
    > > >     clog.rdbuf(b);

    > > Thanks for the advice.
    > > In the original email I was talking about any ostream other
    > > than cout: it might be ofstream, cerr, osstringstream, etc.
    > > Does your code work with <iomanip> (manipulators) ?

    >
    > What do manipulators have to do with streambuf?
    >
    > --
    > James Kanze


    I don't know. That's why I am asking.
    Never mind then. Let me try this approach first.
     
    ksamdev, Sep 10, 2010
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Squid Seven

    ofstream * vs. ofstream

    Squid Seven, Jul 13, 2005, in forum: C++
    Replies:
    5
    Views:
    625
    Ivan Johansen
    Jul 14, 2005
  2. Joe Hesse

    Use cout as ofstream object

    Joe Hesse, Sep 26, 2007, in forum: C++
    Replies:
    5
    Views:
    527
    Salt_Peter
    Sep 26, 2007
  3. Replies:
    5
    Views:
    742
    Jim Langston
    Jan 13, 2009
  4. ksamdev
    Replies:
    3
    Views:
    426
    Stuart Redmann
    Sep 13, 2010
  5. Jeff Flinn
    Replies:
    0
    Views:
    406
    Jeff Flinn
    Sep 11, 2010
Loading...

Share This Page