Predictably formated output with std::cout?

C

Carsten Fuchs

Dear group,

I was wondering what the best way is to produce predictable output with std::cout (and other output
streams)?

That is, one of the biggest weaknesses of std::cout seems to be the fact that a simple statement like

int i=1234;
cout << i;

can yield different outputs depending on the flags set earlier (e.g. decimal, hex or oct numbers).

Due to the global nature of std::cout, any component (e.g. a third-party library or module) of a
program that sets any ios_base flags for its purposes may make the output of std::cout for the rest
of the program entirely unpredictable!

Well, I'm looking for the "best" method in order to solve this unpredictability, or at least for the
most common solutions to the problem.

It's certainly possible to reset or properly set all the flags prior to each cout output manually,
but in practice, that's infeasible (e.g. when one third-party library sets certain flags, and the
other doesn't have the "reset" code) and cumbersome (the flags setup code would be a lot longer than
the actual cout << i; statement).

(Note that good old printf(), despite its many problems and disadvantages, used to be entirely free
of this kind of problem due to its stateless nature. printf("%i", i); though not type-safe and
not useful for custom classes, is short and predictable...)

I'd be very happy about your advice!

Thank you very much in advance, and
best regards,
Carsten
 
S

Stefan Ram

Carsten Fuchs said:
(Note that good old printf(), despite its many problems and
disadvantages, used to be entirely free of this kind of problem
due to its stateless nature. printf("%i", i); though not
type-safe and not useful for custom classes, is short and
predictable...)

Possibly, you can create a new ostream object associated with
stdout and then use this with custom settings instead of cout.
I don't know the details. Maybe something like »new ostream
( new filebuf( stdout, ios_base::eek:ut ))« or so. Possibly, some
care is needed to synchronize this with the standard streams.

Or, you could use a stringstream with its own settings for
formatting and then write the resulting string to ::std::cout
as an unmodified text.
 
G

Gennaro Prota

Carsten said:
[...]
It's certainly possible to reset or properly set all the flags prior to
each cout output manually, but in practice, that's infeasible (e.g. when
one third-party library sets certain flags, and the other doesn't have
the "reset" code) and cumbersome (the flags setup code would be a lot
longer than the actual cout << i; statement).

You might want to look at the I/O Stream-State Saver Library, in Boost.

Personally, I find that they went for a too fine-grained set of
classes and have my own saver, but your mileage may vary. Differently
from Boost, anyway, I have on my side that James Kanze also uses a
single saver class in the code available at his site :) (Seriously,
it's likely that James' code was written way before Boost had a State
Saver library, but still I make a point that his solution is a winner
in terms of simplicity and maintenance cost)
 
A

acehreli

Dear group,

I was wondering what the best way is to produce predictable output with std::cout (and other output
streams)?

That is, one of the biggest weaknesses of std::cout seems to be the fact that a simple statement like

int i=1234;
cout << i;

One option is to leave cout to the others and maintain your own
ostream which shares the same output buffer (but not formatting) with
cout:

#include <iostream>
#include <iomanip>

using namespace std;

void test(const char * label, ostream & os)
{
os << label << ": " << 42 << ' ' << 100 << '\n';
}

int main()
{
ostream mycout(cout.rdbuf());

cout << hex;

test("cout ", cout);
test("mycout", mycout); // not effected by cout's state
}

The output:

cout : 2a 64
mycout: 42 100

Ali
 
V

vova777

  Possibly, you can create a new ostream object associated with
  stdout and then use this with custom settings instead of cout.

That is as simple as -

std::eek:stream out(std::cout.rdbuf());

out << "state free formatted output";

Kind regards,
Vladimir
 
C

Carsten Fuchs

Hi all,

thank you very much to everyone for your answers, they helped a lot!

The boost stream-state saver library sounds good, but I guess that the own ostream instance as
described by Vladimir and Ali, that is:

std::eek:stream out(std::cout.rdbuf());
out << "state free formatted output";

is what I was looking for and fits my case best.

Many thanks for your help!

Best regards,
Carsten
 

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,982
Messages
2,570,186
Members
46,740
Latest member
JudsonFrie

Latest Threads

Top