function to format message & output to cerr/cout/ostream

Discussion in 'C++' started by Trevor, Nov 2, 2003.

  1. Trevor

    Trevor Guest

    Hello,

    Please bear with me, I am trying to learn C++. I am implementing some
    error/debug functions which format a message and output it to a C++ stream.
    I would like to design it using one low level function which accepts a
    "generic C++ stream" as an argument (cerr, cout, ofstream, etc). I have
    tried to make the parameter a const ostream&, but when I plug in cerr or
    cout I get a compiler error. What am I doing wrong?

    // The low level function just formats some message and outputs it to
    "stream".
    void _output(const ostream& stream, const char* reason, int error)
    {
    ostringstream message;
    // ... do some formatting
    if (stream == cerr)
    cerr << message << endl;
    else if (stream == cout)
    cout << message << endl;
    }

    // the high level functions just direct the output to a different stream
    void outputerr(const char* reason, int error)
    {
    // do something special for errors
    _output(cerr, reason, error);
    }

    void outputcmt(const char* reason, int error)
    {
    // do something special for comments
    _output(cout, reason, error);
    }

    void outputwrn(const char* reason, int error)
    {
    // do something special for warnings
    _output(cout, reason, error);
    }

    The compiler error is:

    binary '<<': no operator found which takes a left-hand operand of type
    'const std::eek:stream' (or there is no acceptable conversion)

    on the line of code:

    "stream << message.str().c_str() << endl" // compiler error is in _output()
    Trevor, Nov 2, 2003
    #1
    1. Advertising

  2. Trevor

    Rolf Magnus Guest

    Trevor wrote:

    > Hello,
    >
    > Please bear with me, I am trying to learn C++. I am implementing
    > some
    > error/debug functions which format a message and output it to a C++
    > stream. I would like to design it using one low level function which
    > accepts a
    > "generic C++ stream" as an argument (cerr, cout, ofstream, etc). I
    > have tried to make the parameter a const ostream&, but when I plug in
    > cerr or
    > cout I get a compiler error. What am I doing wrong?
    >
    > // The low level function just formats some message and outputs it to
    > "stream".
    > void _output(const ostream& stream, const char* reason, int error)

    ^^^^^
    Your stream is const, so you cannot write to it.


    > {
    > ostringstream message;
    > // ... do some formatting
    > if (stream == cerr)
    > cerr << message << endl;
    > else if (stream == cout)
    > cout << message << endl;
    > }
    >
    > // the high level functions just direct the output to a different
    > stream void outputerr(const char* reason, int error)
    > {
    > // do something special for errors
    > _output(cerr, reason, error);
    > }
    >
    > void outputcmt(const char* reason, int error)
    > {
    > // do something special for comments
    > _output(cout, reason, error);
    > }
    >
    > void outputwrn(const char* reason, int error)
    > {
    > // do something special for warnings
    > _output(cout, reason, error);
    > }
    >
    > The compiler error is:
    >
    > binary '<<': no operator found which takes a left-hand operand of type
    > 'const std::eek:stream' (or there is no acceptable conversion)


    Right. The operator takes an std::eek:stream&, not a const std::eek:stream&.

    >
    > on the line of code:
    >
    > "stream << message.str().c_str() << endl" // compiler error is in
    > _output()
    Rolf Magnus, Nov 2, 2003
    #2
    1. Advertising

  3. Trevor

    Jeff Guest

    Hi Trevor

    Your code is fine, just remove the "const" before the ostream& in
    _output() (there's no need for the stream to be const, and I'm not
    sure of the internal workings of the << operator, so it might be
    required to not be const... ):

    =================================================

    #include <iostream>
    #include <sstream>
    using namespace std;

    // The low level function just formats some message and outputs it to
    // "stream".
    void _output(ostream& stream, const char* reason, int error)
    {
    ostringstream message;
    // might need a big if/else if/else if to handle formatting for
    each stream
    message << "Here's generic formatting : " << reason << " ... :)
    ....";

    // this code is just the same as that which follows
    // ... do some formatting
    // if (stream == cerr)
    // cerr << message.str() << endl; // did you forget the str()
    here?
    // else if (stream == cout)
    // cout << message.str() << endl; // ditto?

    // assuming you just meant this?
    stream << message.str() << endl; // .c_str() not required

    }


    // the high level functions just direct the output to a different
    stream
    // functions are as you showed them


    int main() {
    outputerr("error here", 2);
    outputcmt("comment", 3);

    return 0;
    }

    ========================================================

    Just a few quick notes, though:

    1. Try to stay away from starting variable and function names with an
    underscore, I don't think this is good style

    2. If you're using the outputXXX (eg outputerr, outputcmt) functions
    in your code, forwarding all of those function calls to another
    routine (_output(), in this case), and then doing all the actual work
    in the called routine /might/ not be a good choice, especially if you
    have extensive checks and branches within the worker function (e.g.,
    if (stream == std::cout) {} else if (stream == std::cerr) {} ... etc
    ....) Why not just do all the formatting etc in the original function
    (outputerr, outputcmt ...)? Mind you, I don't know your design
    choices, so you may have good reasons for this.

    Good luck! Jeff
    Jeff, Nov 2, 2003
    #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. Mike Wahler

    cout & cerr

    Mike Wahler, May 24, 2004, in forum: C++
    Replies:
    1
    Views:
    480
    regisser
    May 24, 2004
  2. Rick N. Backer

    cout, cerr and I/O redirection

    Rick N. Backer, Jul 12, 2005, in forum: C++
    Replies:
    2
    Views:
    339
    Ken Wilson
    Jul 15, 2005
  3. Jim Langston

    Overriding std::cout or std::cerr

    Jim Langston, Aug 14, 2006, in forum: C++
    Replies:
    3
    Views:
    656
    Jim Langston
    Aug 15, 2006
  4. Replies:
    0
    Views:
    434
  5. Will Lichtenberger
    Replies:
    3
    Views:
    3,213
    dener
    Nov 5, 2008
Loading...

Share This Page