Is there a null ostream (like /dev/null) in cpp?

B

Bo Peng

Dear list,

I need to add "disable output" feature to a bunch of objects that output
to ostream (or ofstream). The least intrusive way to do this is pass
them ofstream("/dev/null") but this makes my program less portable. Is
there a null ostream built in cpp? Is it easy to implement one?

Thanks.
Bo
 
J

Jonathan Turkanis

Bo Peng said:
Dear list,

I need to add "disable output" feature to a bunch of objects that output
to ostream (or ofstream). The least intrusive way to do this is pass
them ofstream("/dev/null") but this makes my program less portable. Is
there a null ostream built in cpp?
No.

Is it easy to implement one?

Yes. Derive a class from std::streambuf and override the protected
virtual function overflow as follows

int overflow(int c) { return c; }

Then you can use a standard istream and set its stream buffer to an
instance of your streambuf class using rdbuf. Or you can define your
own derived ostream class which automatically uses an an instance of
your streambuf class.

BTW, Daryle Walker has submitted a null_stream class for inclusion in
Boost, which will be reviewed soon. (See
http://groups.yahoo.com/group/boost/files/more_io_4.zip. (You have to
sign up for the boost developers list to access this:
http://www.boost.org/more/mailing_lists.htm#main.) Also, I have
written an Iostreams Library
(http://home.comcast.net/~jturkanis/iostreams/) which allows a null
ostream to be defined as follows:

struct null_sink : boost::io::sink {
void write(const char*, std::streamsize) { }
};

typedef boost::io::stream_facade<null_sink> null_ostream;

Jonathan
 
S

Siemel Naran

I need to add "disable output" feature to a bunch of objects that output
to ostream (or ofstream). The least intrusive way to do this is pass
them ofstream("/dev/null") but this makes my program less portable. Is
there a null ostream built in cpp? Is it easy to implement one?

You can try o.clear(ios::failbit), and then any statement o << 3 will not do
anything.

You can also set the rdbuf() to NULL in case someone calls o.rdbuf() and
writes to the buffer directly. I'm not sure if the standard allows you to
call o.rdbuf(NULL) though.

Disadvantage:

o.clear(ios::failbit);
o << f(3); // program evaluates f(3) even though it doesn't have to
 
J

JKop

Bo Peng posted:
Dear list,

I need to add "disable output" feature to a bunch of objects that output
to ostream (or ofstream). The least intrusive way to do this is pass
them ofstream("/dev/null") but this makes my program less portable. Is
there a null ostream built in cpp? Is it easy to implement one?

Thanks.
Bo


int cout;


-JKop
 
R

Richard Herring

Dear list,

I need to add "disable output" feature to a bunch of objects that output
to ostream (or ofstream). The least intrusive way to do this is pass
them ofstream("/dev/null") but this makes my program less portable. Is
there a null ostream built in cpp? Is it easy to implement one?

int cout;[/QUOTE]

Yeah, right, that's really helpful.

He never mentions cout; he wants to pass an ostream to an object.

class some_class {
public:
void output_me(std::eek:stream &);
};

some_class x;
int cout;
x.output_me(cout); // and this is going to work how, exactly?
 
J

JKop

It was a joke!

Consider code like this:

using std::cout;

int main()
{
cout << "blah";

cout << "jhskfh";
}


If you stick "int cout" at the start of main(), then it'll
hide the now global scope "cout" object.

Maybe I'm immature, but I find that amusing.


-JKop
 
J

JKop

Rolf Magnus posted:

cout << "Hello world\n";

Allow me to sabotage your prog:


#include <iostream>

using std::cout;


int main()
{
int cout;

cout << "Hello World!!\n";
}



-JKop
 
R

Rolf Magnus

JKop said:
Rolf Magnus posted:



Allow me to sabotage your prog:


#include <iostream>

using std::cout;


int main()
{
int cout;

cout << "Hello World!!\n";
}

g++ says:

fake_cout.cpp: In function `int main()':
fake_cout.cpp:10: error: invalid operands of types `int' and `const
char[15]' to binary `operator<<'

And even if this worked as you might have expected, how would it satisfy
the OP's request for a stream that just throws everything away?
 
R

Rolf Magnus

JKop said:
It was a joke!

Consider code like this:

using std::cout;

int main()
{
cout << "blah";

cout << "jhskfh";
}


If you stick "int cout" at the start of main(), then it'll
hide the now global scope "cout" object.

Maybe I'm immature, but I find that amusing.

Doesn't look immature to me, but I can't find anything funny in that
either.
 
J

Jonathan Turkanis

Yes. Derive a class from std::streambuf and override the protected
virtual function overflow as follows

int overflow(int c) { return c; }

Strictly, this is wrong if c == EOF. For an arbitrary character and
traits type, the implementation would be

int_type overflow(int_type c)
{
return traits_type::not_eof(c);
}

For the case discussed, int overflow(int c) { return 0; }should
suffice.

Jonathan
 
B

Bo Peng

Siemel said:
You can try o.clear(ios::failbit), and then any statement o << 3 will not do
anything.

o.clear(ios::failbit);
o << f(3); // program evaluates f(3) even though it doesn't have to

This seems to be an easy solution but in practice I have to create 'o'
in some way. As far as I know, I can not instantiate ostream like
ostream o;
o.clear(.....)
and if I use
ofstream o(...)
I have to use a valid filename which will create an empty file even if I
do not write anything to it.

Of course it is a bad idea to cripple cout or cerr by
cout.clear(ios::failbit).

I guess I will follow Jonathan's method.

Bo Peng
 
S

Siemel Naran

Bo Peng said:
Siemel Naran wrote:

This seems to be an easy solution but in practice I have to create 'o'
in some way. As far as I know, I can not instantiate ostream like
ostream o;
o.clear(.....)
and if I use
ofstream o(...)
I have to use a valid filename which will create an empty file even if I
do not write anything to it.

If you use an invalid filename, the stream will have the failbit and
possibly the badbit set. Why is it important to instantiate o with the
failbit set, and what's wrong with ostream o followed by
o.clear(ios::failbit)?
Of course it is a bad idea to cripple cout or cerr by
cout.clear(ios::failbit).

I guess I will follow Jonathan's method.

Yes, it is cleaner. But it's also not a good idea to replace the underlying
streambuf of cout, cerr. If you do, remember to restore the original
streambuf, else the program may crash at program termination.
 

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,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top