redefining cout (for using printf/mexprintf)

Discussion in 'C++' started by uli, Apr 20, 2004.

  1. uli

    uli Guest

    Hi all!
    I'm posting to both newsgroups, because it's actually a C++ problem but
    could be that some of you using Matlab-&-MEX-&-C++ was struggling with the
    same problem.

    I'm trying to rewrite some Matlab routines in C++ for reusing them
    identically in Matlab and some other simulation tools. For computational
    algebra I want to use the Matrix Template Library (MTL,
    http://www.osl.iu.edu/research/mtl/) which is written in C++ and therefore
    makes use of std::cout.
    I have to use the mexfunction-interface of Matlab to run C++ code within a
    Matlab simulation. Since I'm writing my code with MSVC++ 6.0 and running
    Matlab on Windows, together with MATLAB and MEX, I can't use "cout" but
    "printf" ('cause of the MSWindows specific Matlab-Terminal).


    However to come to my Problem now:
    To solve this I want to redefine std::cout (within a header of my individual
    MEXinterface.cpp) so that it makes use of printf() instead . Could someone
    give me some hints or links to information how I could manage this?
    I know that it must be tricky since cout prints stream?! So I need to
    transform the stream in strings??
    Perhaps as a last resort, if it can't be done, any "std::cout << ... "
    should print a infomessage.

    I know it's not a good way to redefine some functions of the std namespace.
    I have never done something like this. But it seems to me to be the only way
    out. I also just want to use this redefinition together with Matlab-&-MEX
    and probably won't make much use of MTL specific printouts...


    thanx a lot of for any kind of help!
    regards,
    uli
    --
    For reply remove NOSPAM_ from email-adress
    uli, Apr 20, 2004
    #1
    1. Advertising

  2. "uli" <> wrote in message news:<c62sdn$p8q$>...
    > Hi all!
    > I'm posting to both newsgroups, because it's actually a C++ problem but
    > could be that some of you using Matlab-&-MEX-&-C++ was struggling with the
    > same problem.
    >
    > I'm trying to rewrite some Matlab routines in C++ for reusing them
    > identically in Matlab and some other simulation tools. For computational
    > algebra I want to use the Matrix Template Library (MTL,
    > http://www.osl.iu.edu/research/mtl/) which is written in C++ and therefore
    > makes use of std::cout.
    > I have to use the mexfunction-interface of Matlab to run C++ code within a
    > Matlab simulation. Since I'm writing my code with MSVC++ 6.0 and running
    > Matlab on Windows, together with MATLAB and MEX, I can't use "cout" but
    > "printf" ('cause of the MSWindows specific Matlab-Terminal).
    >
    >
    > However to come to my Problem now:
    > To solve this I want to redefine std::cout (within a header of my individual
    > MEXinterface.cpp) so that it makes use of printf() instead . Could someone
    > give me some hints or links to information how I could manage this?


    Sure, it's not very complex. Inside std::cout, there is something called
    a streambuf. The default streambuf is responsible for writing the
    already formatted text to the console (formatting was done by the
    std::cout object itself). If you want to send the text to a different
    destination, you will have to replace the streambuf. E.g. if you
    want to redirect std::cout to a file, open a std::eek:fstream, and swap
    the streambufs. If you have another destination, derive your
    custom sterambuf from std::streambuf and implement the applicable
    virtual functions.
    Pointer: std::stream::rdbuf(std::streambuf*).

    Regards,
    Michiel Salters
    Michiel Salters, Apr 20, 2004
    #2
    1. Advertising

  3. "uli" <> wrote:
    > To solve this I want to redefine std::cout (within a header of my individual
    > MEXinterface.cpp) so that it makes use of printf() instead . Could someone
    > give me some hints or links to information how I could manage this?


    You should not try to "redefine std::cout". What you can do is to replace
    the stream buffer used by 'std::cout' with a stream buffer writing to a
    new destination, eg. to 'printf()' (although the destinations of 'printf()
    and 'std::cout' should actually be identical).

    > I know that it must be tricky since cout prints stream?! So I need to
    > transform the stream in strings??


    Streams write the chars to stream buffers. These collect the chars in a
    buffer which can then be easily handed to whatever function you want to
    use. This is the way I would go, anyway.
    --
    <mailto:> <http://www.dietmar-kuehl.de/>
    <http://www.contendix.com> - Software Development & Consulting
    Dietmar Kuehl, Apr 20, 2004
    #3
  4. uli

    uli Guest

    "Dietmar Kuehl" <> wrote in message
    > "uli" <> wrote:
    > > To solve this I want to redefine std::cout (within a header of my

    individual
    > > MEXinterface.cpp) so that it makes use of printf() instead . Could

    someone
    > > give me some hints or links to information how I could manage this?

    >
    > You should not try to "redefine std::cout". What you can do is to replace
    > the stream buffer used by 'std::cout' with a stream buffer writing to a
    > new destination, eg. to 'printf()' (although the destinations of 'printf()
    > and 'std::cout' should actually be identical).
    >
    > > I know that it must be tricky since cout prints stream?! So I need to
    > > transform the stream in strings??

    >
    > Streams write the chars to stream buffers. These collect the chars in a
    > buffer which can then be easily handed to whatever function you want to
    > use. This is the way I would go, anyway.



    Ok, I tried to figure it out with my STL literature. But it seems, that I'am
    not really good in C++!
    I now know to redirect cout to a file with:
    #include <fstream.h>
    filebuf *pBuf = new filebuf;
    pBuf->open("cout.txt", ios::eek:ut);
    cout = pBuf;

    // ... more code

    delete cout.rdbuf();

    But for redirecting it to another function how can I change the streambuf*
    to 'string' then, like:
    #include <iostream>
    std::streambuf* str_buf = std::cout.rdbuf();
    printf("%s", *str_buf); //<<< doesn't work of course!


    thanx, once again!
    uli
    uli, Apr 20, 2004
    #4
  5. uli

    Jack Walker Guest

    "uli" <> wrote in message news:<c63l8a$4rc$>...
    > "Dietmar Kuehl" <> wrote in message
    > > "uli" <> wrote:
    > > > To solve this I want to redefine std::cout (within a header of my

    > individual
    > > > MEXinterface.cpp) so that it makes use of printf() instead . Could

    > someone
    > > > give me some hints or links to information how I could manage this?

    > >
    > > You should not try to "redefine std::cout". What you can do is to replace
    > > the stream buffer used by 'std::cout' with a stream buffer writing to a
    > > new destination, eg. to 'printf()' (although the destinations of 'printf()
    > > and 'std::cout' should actually be identical).
    > >
    > > > I know that it must be tricky since cout prints stream?! So I need to
    > > > transform the stream in strings??

    > >
    > > Streams write the chars to stream buffers. These collect the chars in a
    > > buffer which can then be easily handed to whatever function you want to
    > > use. This is the way I would go, anyway.

    >
    >
    > Ok, I tried to figure it out with my STL literature. But it seems, that I'am
    > not really good in C++!
    > I now know to redirect cout to a file with:
    > #include <fstream.h>
    > filebuf *pBuf = new filebuf;
    > pBuf->open("cout.txt", ios::eek:ut);
    > cout = pBuf;
    >
    > // ... more code
    >
    > delete cout.rdbuf();
    >
    > But for redirecting it to another function how can I change the streambuf*
    > to 'string' then, like:
    > #include <iostream>
    > std::streambuf* str_buf = std::cout.rdbuf();
    > printf("%s", *str_buf); //<<< doesn't work of course!
    >

    Try stringstream for in core formatted output:

    ostringstream sout ;

    sout << "stuff to write out" << endl ;

    ..
    ..
    ..


    mexprintf("%s", sout.c_str()) ;



    Jack Walker

    >
    > thanx, once again!
    > uli
    Jack Walker, Apr 21, 2004
    #5
  6. uli wrote:
    > Ok, I tried to figure it out with my STL literature.


    STL literature would not cover anything related to streams (with the
    exception of the various stream iterators) since streams are not part
    of the STL: the STL is a library which essentially became the
    functional, algorithms, iterators, and containers library of the
    standard C++ library. That is STL != standard C++ library.

    > But for redirecting it to another function how can I change the streambuf*
    > to 'string' then, like:


    Well, this is not exactly what you probably want to do but you could
    use a 'std::stringbuf' at first:

    #include <iostream>
    #include <sstream>
    int main() {
    std::streambuf* cout_sbuf = std::cout.rdbuf();
    std::stringbuf sbuf;
    std::cout.rdbuf(&sbuf);
    // ...
    printf("stream contents: %s\n", sbuf.str().c_str());
    std::cout.rdbuf(cout_sbuf);
    }

    It is relatively important that you restore the original stream buffer
    into the stream because after exiting 'main()' the standard stream
    objects may be flushed (due to the behavior of the destructor of
    'std::ios_base::Init'). Since the installed stream buffer is destructed
    by then, this would result in a crash during program termination which
    is generally not the best behavior and may even cause havoc on some of
    the data which is not yet flushed.

    However, I was actually not refering to installing one of the existing
    stream buffers since these don't really do the right thing. You want
    to create your own stream buffer by deriving from 'std::streambuf' and
    overriding the 'overflow()' and 'sync()' methods. The tricky part in
    your particular setup is that you apparently have two routes to write
    output:
    - you might use 'std::cout' to write output
    - you might use the underlying mechanism directly to write output
    In situations like this you get synchronization problems if you are
    not careful and do buffering in the stream buffer. On the other hand,
    using an unbuffered stream buffer is likely to cause a performance
    problem. You might compromise on setting the 'unitbuf' flag which will
    flush the stream after every insertion operation. Another alternative
    is to terminate all uses of 'std::cout' with 'std::endl' or 'std::flush'
    (the difference between these two is that the former adds a newline
    prior to the flush; in general, I recommend against use of 'std::endl'
    because it mixes two entirely separate issues but sometimes it just has
    the right semantics...).

    A simple stream buffer for your purpose would look something like this:

    struct printfbuf: std::streambuf {
    enum { s_size = 1024 };
    printfbuf() { setp(m_buffer, m_buffer + s_size - 2); }
    private:
    int_type overflow(int_type c) {
    if (!traits_type::eq_int_type(c, traits_type::eof()) {
    *pptr() = traits_type::to_char_type(c);
    pbump(1);
    }
    return sync() != -1? traits_type::not_eof(c): traits_type::eof();
    }
    int sync() {
    *pptr() = 0;
    printf(pbase());
    setp(m_buffer, m_buffer + s_size - 2);
    return 0;
    }
    char m_buffer[s_size];
    };

    This code is not tested (not even compiled) and I guess I forgot
    something important. However, to find out more about implementing
    stream buffers, you can have a look at various resources:
    - Nicolai Josuttis' book "The C++ Standard Library" (Addison-Wesley)
    describes this stuff (actually, I have translated/rewritten this
    section)
    - Angelika Langer and Klaus Kreft's book "C++ IOStreams and Locales"
    (Addison-Wesley) covers this stuff in depth
    - I have written loads of articles in newsgroup (use eg.
    <http://group.google.com/> to locate past articles)
    --
    <mailto:> <http://www.dietmar-kuehl.de/>
    <http://www.contendix.com> - Software Development & Consulting
    Dietmar Kuehl, Apr 21, 2004
    #6
    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. abi

    man cout or info cout

    abi, Jun 27, 2003, in forum: C++
    Replies:
    2
    Views:
    1,649
  2. Pmb

    std::cout vs cout

    Pmb, Jun 2, 2004, in forum: C++
    Replies:
    2
    Views:
    4,405
    Leor Zolman
    Jun 2, 2004
  3. Replies:
    4
    Views:
    317
    Howard
    Sep 15, 2005
  4. Stefan Ram

    Re: cout vs std::cout

    Stefan Ram, Sep 28, 2008, in forum: C++
    Replies:
    7
    Views:
    478
  5. Hendrik Schober

    Re: cout vs std::cout

    Hendrik Schober, Sep 28, 2008, in forum: C++
    Replies:
    7
    Views:
    440
    Jerry Coffin
    Oct 7, 2008
Loading...

Share This Page