473,396 Members | 1,764 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Creating own IO streams

I'd like to create my own output streams, in order to be able to
redirect output strings to a console, a status window or whatever,
depending on the environment. For example, IO::warning << "Bad stuff";
could output a string on stderr to start with, and when I have written
a nice GUI, it could be output to a status window or a log file or
something.

I have written a skeleton file which looks like this:

//---------------------
#include <iostream>
#include <string>

namespace IO
{
template <class charT, class Traits=std::char_traits<charT> >
class My_Ostream : public std::basic_ostream< charT, Traits >
{
public:
My_Ostream( std::basic_streambuf< charT, Traits >* sb =
std::cerr.rdbuf())
: std::basic_ostream< charT, Traits >( sb )
{
its_sb = sb;
}

std::basic_ostream<charT, Traits>& operator <<
( charT& input )
{
its_sb << "[" << input << "]";
}

private:
std::basic_streambuf< charT, Traits >* its_sb;
};

// IO::warning is just std::cerr.
My_Ostream< char, std::char_traits<char> > warning(
std::cerr.rdbuf() );

}
//---------------------

When calling
IO::warning << "Yo";
I'm expecting the output "[Yo]" on cerr, but I'm just getting "Yo".

Can anybody help me with a proper definition of the << operator?
Jul 22 '05 #1
6 3662
Martin Magnusson wrote:

I'd like to create my own output streams, in order to be able to
redirect output strings to a console, a status window or whatever,
depending on the environment. For example, IO::warning << "Bad stuff";
could output a string on stderr to start with, and when I have written
a nice GUI, it could be output to a status window or a log file or
something.


Your attempt is flawed.
Instead of writing a new stream class you should configure
an ordinary ostream object to do what you want. You do this
by writing a new streambuf class and tell the ostream object
to use that instead of the one it has.

Search this group or the web for postings of 'Dietmar Kuehl'. He
has shown a number of times how this is done.

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 22 '05 #2
"Martin Magnusson" <lo*******@frustratedhousewives.zzn.com> wrote in message
template <class charT, class Traits=std::char_traits<charT> >
class My_Ostream : public std::basic_ostream< charT, Traits >
{
public:
My_Ostream( std::basic_streambuf< charT, Traits >* sb =
std::cerr.rdbuf())
: std::basic_ostream< charT, Traits >( sb )
{
its_sb = sb;
}

std::basic_ostream<charT, Traits>& operator <<
( charT& input )
{
its_sb << "[" << input << "]";
}

private:
std::basic_streambuf< charT, Traits >* its_sb;
};


You should not override non-virtual function. You override operator<<(char)
but your call to stream << "yo" looks for operator<<(const char *) and
therefore calls the base class version.

In your approach, don't use public inheritance. Also, provide a template
operator<< function. Consider renaming output argument 'input' too :).

template <class T>
std::basic_ostream<charT, Traits>& operator <<
( const T& object)
{
its_sb << "[" << object << "]";
}

But its_sb has to be a pointer or reference to a stream, not a streambuf or
pointer to one.

You should also research the streambuf method suggested by Karl, namely
overriding overflow.

Both solutions have been posted to these newsgroups and
comp.lang.c++.moderated.
Jul 22 '05 #3
Karl Heinz Buchegger <kb******@gascad.at> wrote:
Search this group or the web for postings of 'Dietmar Kuehl'. He
has shown a number of times how this is done.


I did that, and tried to implement one of the examples posted at his
web site. There seems to be a problem with inheritance that I don't
quite understand, though. I get the following message, both with g++
and Dev-C++:

/usr/include/c++/3.3.1/streambuf: In member function `virtual int
Prefixed_Stream_Buffer::sync()':
/usr/include/c++/3.3.1/streambuf:749: error: `int
std::basic_streambuf<_CharT, _Traits>::sync() [with _CharT = char,
_Traits = std::char_traits<char>]' is protected
IO.cpp:40: error: within this context

The relevant code looks like this:

#include <iostream>

class Prefixed_Stream_Buffer: public std::streambuf
{
public:
Prefixed_Stream_Buffer( std::streambuf *sb, const char* prefix );

protected:
int overflow( int c );
int sync();

private:
std::streambuf *its_sb;
const char* its_prefix;
int its_prefix_length;
bool it_has_pending_newline;
};

int Prefixed_Stream_Buffer::sync()
{
its_sb->sync(); // ERROR HERE (LINE 40)
return 0;
}
Jul 22 '05 #4

"Martin Magnusson" <lo*******@frustratedhousewives.zzn.com> wrote in message
news:35**************************@posting.google.c om...
Karl Heinz Buchegger <kb******@gascad.at> wrote:
Search this group or the web for postings of 'Dietmar Kuehl'. He
has shown a number of times how this is done.


I did that, and tried to implement one of the examples posted at his
web site. There seems to be a problem with inheritance that I don't
quite understand, though. I get the following message, both with g++
and Dev-C++:

/usr/include/c++/3.3.1/streambuf: In member function `virtual int
Prefixed_Stream_Buffer::sync()':
/usr/include/c++/3.3.1/streambuf:749: error: `int
std::basic_streambuf<_CharT, _Traits>::sync() [with _CharT = char,
_Traits = std::char_traits<char>]' is protected
IO.cpp:40: error: within this context

The relevant code looks like this:

#include <iostream>

class Prefixed_Stream_Buffer: public std::streambuf
{
public:
Prefixed_Stream_Buffer( std::streambuf *sb, const char* prefix );

protected:
int overflow( int c );
int sync();

private:
std::streambuf *its_sb;
const char* its_prefix;
int its_prefix_length;
bool it_has_pending_newline;
};

int Prefixed_Stream_Buffer::sync()
{
its_sb->sync(); // ERROR HERE (LINE 40)
return 0;
}


Right sync is protected so you cannot access it through a pointer like that,
the fact that you are in a method of a class derived from streambuf is
irrelevant, many people don't understand this.

Use the public version of sync instead, called pubsync.

int Prefixed_Stream_Buffer::sync()
{
return its_sb->pubsync();
}

john
Jul 22 '05 #5
Martin Magnusson wrote:

Karl Heinz Buchegger <kb******@gascad.at> wrote:
Search this group or the web for postings of 'Dietmar Kuehl'. He
has shown a number of times how this is done.


I did that, and tried to implement one of the examples posted at his
web site. There seems to be a problem with inheritance that I don't
quite understand, though. I get the following message, both with g++
and Dev-C++:


mail Dietmar directly.
His mail address is given on the web site.

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 22 '05 #6
lo*******@frustratedhousewives.zzn.com (Martin Magnusson) wrote:
I did that, and tried to implement one of the examples posted at his
web site. There seems to be a problem with inheritance that I don't
quite understand, though. I get the following message, both with g++
and Dev-C++:

/usr/include/c++/3.3.1/streambuf: In member function `virtual int
Prefixed_Stream_Buffer::sync()':
/usr/include/c++/3.3.1/streambuf:749: error: `int
std::basic_streambuf<_CharT, _Traits>::sync() [with _CharT = char,
_Traits = std::char_traits<char>]' is protected
IO.cpp:40: error: within this context
This error message just says that 'sync()' cannot be called from outside
the object, not even from another class also derived from 'std::streambuf'
(this is due to the way protected members work). Actually, the 'sync()'
method was public in the IOStreams prior to standardization. It was turned
into two functions, 'sync()' and 'pubsync()', with the former being virtual
and protected and the latter being public and non-virtual. 'pubsync()'
merely forwards the request to 'sync()'. Thus, this problem should be easy
to fix:
int Prefixed_Stream_Buffer::sync()
{
its_sb->sync(); // ERROR HERE (LINE 40)
Just replace the above line by

its_sb->pubsync();
return 0;
}


The code at the website is somewhat aged by now and is mostly written to
prestandard libraries. I haven't come around to updating it and this task
is also not really high on my priority list...
--
<mailto:di***********@yahoo.com> <http://www.dietmar-kuehl.de/>
<http://www.contendix.com> - Software Development & Consulting
Jul 22 '05 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

21
by: Jason Heyes | last post by:
I want to allow objects of my class to be read from an input stream. I am having trouble with the implementation. Here are the different approaches I have tried: // Version 1.0 - Default...
3
by: Tron Thomas | last post by:
What does binary mode for an ofstream object do anyway? Despite which mode the stream uses, operator << writes numeric value as their ASCII representation. I read on the Internet that it is...
8
by: bonj | last post by:
hello I hope somebody can help me get my head around this area of 'stream' programming... I know that streams are very fashionable nowadays so hopefully there'll be lots of replies. ;-) ...
11
by: Kobu | last post by:
I have a question about C's abstract "streams" (that I can't seem to FULLY understand from reading several tutorials). Streams seems to suggest that input can be treated continously if needed....
2
by: bonk | last post by:
Hello how do I connect streams in c# ? Imagine the followung scenario: I have a StreamWriter that writes Text to a Stream. How can I tell that Stream to pass that Data to another Stream...
1
by: Chris | last post by:
I'm reading up on streams and I have two articles that seem to conflict with each other. One article describes streams and lists a few of the major ones (FileStream, Memory Stream, Network...
7
by: Nathan Sokalski | last post by:
I am having a problem saving an image with the same name it originally had. I have two similar versions of my code, one in which I close the FileStream used to open the original image before saving,...
11
by: Diego Martins | last post by:
for me, these items are in the 'tricky zone' of C++ does anyone know good material with that? (dealing with subtle details, pitfalls, good practices...) anything like the Effective series from...
2
by: swatibksh | last post by:
can i create two input streams for a single socket ? and can it is possible to use those 2 streams simultaneously ?? can it be done using clone object ?
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.