Custom C++ stream

Started by
8 comments, last by Shannon Barber 21 years, 1 month ago
I want to make a logger class that dumps messages onto the screen, and I''d like to make it work like the iostream clases. Now, unfortunetly most of my C++ resources predate the standard, and the ones that don''t stear clear of iostreams, so my understanding of this portion of C++ isn''t stellar. I''d like to be able to write this: logger << "OnConnect (0x" << hex << some_pointer << ")" << endl; It appears that flush is a function on the buffer, not on the stream object, so do I have to derive from a buffer and make my own custom buffer and stream objects? Is there a more direct way to do what I want?
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
Advertisement
I think you can do it pretty easy :

Give Logger a member variable of type ofstream (the file to write to), then all you have to do is add a template member function to logger :


    template<class T>Logger & Logger::operator << (const T &  t){     file << t;        // file is the file to write to     return *this;}    




[edited by - George2 on March 23, 2003 6:50:56 AM]
"THE INFORMATION CONTAINED IN THIS REPORT IS CLASSIFIED; DO NOT GO TO FOX NEWS TO READ OR OBTAIN A COPY." , the pentagon
The idea with iostreams is that you don't derive your own stream classes, you derive your own streambufs. Derivation of new stream classes is generally only done to save you from having to explicitly initialise an istream/ostream yourself (which is rarely that much of a hardship, really).

For this kind of application, you only need to derive a streambuf that supports output. I give you this example copied almost verbatim from the Josuttis standard library book, "The C++ Standard Library - A Tutorial and Reference":

    #include <iostream>class outbuf : public std::streambuf{  protected:    /* central output function     * - print characters in uppercase mode     */    virtual int_type overflow (int_type c) {        if (c != EOF) {            // write the character to the standard output            if (putchar(c) == EOF) {                return EOF;            }        }        return c;    }};int main(){    outbuf ob;                // create special output buffer    std::ostream out(&ob);    // initialize output stream with that output buffer    out << "31 hexadecimal: " << std::hex << 31 << std::endl;}    

Obviously in your application you may want to appropriately template-ize the class so it can be used for different character types and different char_traits, etc. And this is the minimal, inefficient version. You will probably want to define xsputn() too in order to accommodate efficient writing of multiple values.

[ MSVC Fixes | STL Docs | SDL | Game AI | Sockets | C++ Faq Lite | Boost
Asking Questions | Organising code files | My stuff | Tiny XML | STLPort]

[edited by - Kylotan on March 23, 2003 9:08:37 AM]
Is it ok to have few streams sharing the same ob object?
"after many years of singularity, i'm still searching on the event horizon"
No, only one stream can use a stream buffer at a time.

Also, I was intending to use a stringstream, as I do not want/need to open a file. I''m trying to put the strings on the screen in a listbox, and want to switch to the next item in the list when a flush occurs.

The stringstream classes do not appear to have a ctor that accepts a stringbuf to operate on.
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara
Magmai, why not just use the standard clog class? If I''m not mistaken it defaults to displaying on the screen. If you later want it redirect its output to file or debugger or messagebox, just change the streambuf on the fly like so:

clog.rdbuf(file.rdbuf());

Also, flush is a manipulator and it can be used like so:

clog << "my text" << std::flush;

However, if you use std::endl it flushes automatically.

For the record, that''s what I''m doing but I''m going to create my own log class that''s derived from a C++ stream. The reason is I''m going to include functions to allow the user to add/remove multiple streambufs so the logger can actually log to more than one location at a time (ie, screen, debugger, and to file).


- Houdini
- Houdini
This seems like a good time to ask: does anyone know where I could find information on writing buffered streambufs?
google @ cuj.com, I seem to remember there was some stuff on stream buffers.
Also, I think the boost file group at yahoo has examples, as does libGDN (but, I think is far more complex then what you neeed).

-----------------------------
Gamedev for learning.
libGDN for putting it all together.
quote:Original post by risingdragon3
google @ cuj.com, I seem to remember there was some stuff on stream buffers.
Hmmm... yep, there certainly is. Thanks!
"Standard C++ IOStream and Locales" by Langer & Kreft


[ Start Here ! | How To Ask Smart Questions | Recommended C++ Books | C++ FAQ Lite | Function Ptrs | CppTips Archive ]
[ Header Files | File Format Docs | LNK2001 | C++ STL Doc | STLPort | Free C++ IDE | Boost C++ Lib | MSVC6 Lib Fixes ]
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan

This topic is closed to new replies.

Advertisement