Overloading / Getting rid of cout

J

John Harrison

Philip Lawatsch said:
Hi,

I'd like to get rid of all the cout stuff in my code.

Following situation:

Way over 2000 files, search and replace in all of them is not an option.
All of the files include a basic header.
In this basic header i must NOT include iostream.
Iostereams thus get included after my basic header, at any random place
in the code.

What I'd like to do is change the behaviour in a way that everything
sent to either cout or cerr comes to my own stream class (which is
accessible by including the base header) or can at least be supressed
(this is easy though)

with kind regards Philip

Search and replace is the correct option, write a program to do it, or if
you are on Unix/Linux use a tool like sed or awk.

john
 
P

Philip Lawatsch

Hi,

I'd like to get rid of all the cout stuff in my code.

Following situation:

Way over 2000 files, search and replace in all of them is not an option.
All of the files include a basic header.
In this basic header i must NOT include iostream.
Iostereams thus get included after my basic header, at any random place
in the code.

What I'd like to do is change the behaviour in a way that everything
sent to either cout or cerr comes to my own stream class (which is
accessible by including the base header) or can at least be supressed
(this is easy though)

with kind regards Philip
 
P

Philip Lawatsch

John Harrison wrote:

Search and replace is the correct option, write a program to do it, or if
you are on Unix/Linux use a tool like sed or awk.

Well, I'm aware that this would be a correct solution, but I'm afraid i
just can't do this.

Thus I was looking for something else, perhaps some special stuff the
iostreams provide for this


with kind regards Philip
 
P

Philip Lawatsch

John said:
You can redirect cout. Forget the exact syntax but its something like

int main()
{
streambuf* save_buffer = cout.rdbuf(my_stream.rdbuf());
...
cout.rdbuf(save_buffer);
}


Hmmm, nice thought, though this leads to a problem.
Using this approach it seems that my code (my stream code) won't get
called when data is written, and this would result in a huge buffer needed.

(One of the reasons I'd like to get rid of all this couts is that huge
amounts of output are written out).

Also, using this approach I could not easily filter the output I get and
only write some of the stuff out because I could only do it when I'm
inside the my stream class. Thus this would result in a huge lagg of
output since some parts of our code run for several minutes until
controll returns to some part where I could initiate parsing this buffer.


with kind regards Philip
 
T

tom_usenet

I see ...

For portability issues (we're compiling on more than 6 unices, linux and
windows).

Due to crappy compilers and ill behaved std libs we tried to code as
much of the basis framework ourselves as possible, and thus my stream
class is not derived from streambuf.

I'll have a look at this option !

What have you got currently? What does your stream class look like? If
you haven't derived from streambuf, I'm curious as to how your stream
class works. Is it completely independent of the iostreams heirarchy?

Tom
 
P

Philip Lawatsch

What have you got currently? What does your stream class look like? If
you haven't derived from streambuf, I'm curious as to how your stream
class works. Is it completely independent of the iostreams heirarchy?

Yep, it is

I'm sorry, i just cant paste the source here, but in prinziple its a
class with stream ops for the basic data types defined (virtual).

And then some derived classes for streaming to files, the console, the
gui etc.

And my objects implement stream operators for my basic stream class.

This thing does not support everything the iostreams do, but enough for
my app.

Ohh, and, yes, my stream class cant be mixed with anything from iostream
since they dont know each other.


with kind regards philip
 
T

tom_usenet

Yep, it is

I'm sorry, i just cant paste the source here, but in prinziple its a
class with stream ops for the basic data types defined (virtual).

And then some derived classes for streaming to files, the console, the
gui etc.

And my objects implement stream operators for my basic stream class.

How do you manage to have cout calls in the code then? If your classes
don't implement operator<< for ostream, then cout calls won't work. Or
perhaps the cout calls only use the built in types?
This thing does not support everything the iostreams do, but enough for
my app.

Ohh, and, yes, my stream class cant be mixed with anything from iostream
since they dont know each other.

Well, I won't chastise you for reinventing the wheel (and making it a
bit less round than current wheel designs), but instead tell you that
you can't redirect std::cout to anything but another streambuf. Where
exactly do you want to redirect it to? You obviously can't direct it
to your stream class, but you can get it to write to the same thing
that your stream class is writing to, but creating a streambuf class
that outputs to that (note this can be unbuffered if you choose -
streambuf is a slightly misleading name).

You can supress cout output with a call to:

std::streambuf* oldcout = std::cout.rdbuf(0);


//reset before exit:
std::cout.rdbuf(oldcout);

Still, from what you're saying, search and replace is by far the best
option.

Tom
 
P

Philip Lawatsch

tom_usenet said:
How do you manage to have cout calls in the code then? If your classes
don't implement operator<< for ostream, then cout calls won't work. Or
perhaps the cout calls only use the built in types?

Well, this is exactly the point.
There should not be any calls to cout directly, but a lot of developers
just give a damn about design rules, and exchanging them is not an option.
So something has to be done to get rid of the problem.

If I just search and replace this won't keep any of them from adding new
couts and thus this would be a never ending stuff
Well, I won't chastise you for reinventing the wheel (and making it a
bit less round than current wheel designs), but instead tell you that
you can't redirect std::cout to anything but another streambuf.

But I can (and am working on that currently) write a dummy stream class
derived from streambuf as a wrapper.
Not nice, and i just cross my fingers that this will be portable (I do
have bad experiences about such stuff, this is why we wrote as much
ourselves as possible in the first place)
Where
exactly do you want to redirect it to? You obviously can't direct it
to your stream class, but you can get it to write to the same thing
that your stream class is writing to, but creating a streambuf class
that outputs to that (note this can be unbuffered if you choose -
streambuf is a slightly misleading name).

You can supress cout output with a call to:

std::streambuf* oldcout = std::cout.rdbuf(0);


//reset before exit:
std::cout.rdbuf(oldcout);

Well, what i'll do is write a wrapper using a class derived from
streambuf and then distribute it to appropriate calls in our framework

Its not nice what I'm doing, and I am aware that such a situation should
never happen if just everyone would follow design guidelines, but if
you've ever worked in mid size projects you might know that you can't
just make everyone do what you want him to do.


with kind regards Philip
 
P

Philip Lawatsch

tom_usenet wrote:

Assuming you don't want buffering (which might interfere with other
usages of your stream class), you just need to override overflow:

class MyStreambuf: public std::streambuf
{
MyStream& m_stream;
public:
MyStreambuf(MyStream& s)
:m_stream(s)
{
}

protected:
int overflow(int c)
{
if (c != EOF)
{
char cc = traits_type::to_char_type(c);
m_stream.put(c); //or whatever puts a char
}
return traits_type::not_eof(c);
}

//optional
int sync()
{
m_stream.flush();
return 0;
}
};

And that's it. Inefficient (I virtual function call per character
output), but that probably doesn't matter to you.

This is in principle what I'm doing right now :)

Thanks for all the ideas

with kind regards Philip
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top