Manipulator question...

B

barcaroller

When I use an iostream manipulator in a cout statement, it seems to affect
all subsequent cout statements.

cout << x << endl; // dec by default
cout << hex << x << endl; // hex
cout << x << endl // still hex

Is there a way I can have manipulators affect only the "current" cout
statement?
 
P

Pete Becker

barcaroller said:
When I use an iostream manipulator in a cout statement, it seems to affect
all subsequent cout statements.

cout << x << endl; // dec by default
cout << hex << x << endl; // hex
cout << x << endl // still hex

Is there a way I can have manipulators affect only the "current" cout
statement?

Save the stream's formatting flags, manipulate it, and when you're done,
restore the flags. For that you'll need to read about the
ios_base::flags functions.

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
 
B

BobR

barcaroller said:
When I use an iostream manipulator in a cout statement, it seems to affect
all subsequent cout statements.

cout << x << endl; // dec by default
cout << hex << x << endl; // hex
cout << x << endl // still hex

Is there a way I can have manipulators affect only the "current" cout
statement?

What Pete said.
But, for a few dollars more, there is another way:

{ // main or function
{ // scope1
std::eek:stringstream sos;
sos << x << endl; // dec by default
sos << hex << x << endl; // hex
cout << sos.str() <<endl;
} // scope1
cout << x << endl; // as normal (default)
}

Now you are not changing std::cout.
In case you can't do that, here is a short example:

{ // main of func
std::ios_base::fmtflags oldFlg =
cout.setf(std::ios_base::fixed, std::ios::floatfield);
int OutPre = cout.precision(40); // save prec, change to 40
// ------- use it here
// Case2Com Case2;
// Case2.execute(cout);
// -------
cout.setf( oldFlg, std::ios::floatfield ); // reset what you need
cout.precision( OutPre ); // restore orig precision
}

Here you pay another price, you need to 'reset' everything you changed.
Notice that using the stringstream way (in a scope), you do not need to
'reset' it, just let it go out of scope (destruct).
 
J

James Kanze

What Pete said.
But, for a few dollars more, there is another way:
{ // main or function
{ // scope1
std::eek:stringstream sos;
sos << x << endl; // dec by default
sos << hex << x << endl; // hex
cout << sos.str() <<endl;} // scope1

cout << x << endl; // as normal (default)
}
Now you are not changing std::cout.

That's definitly the most certain. On the other hand, it's a
lot of extra effort, and rather heavy and cumbersome.
In case you can't do that, here is a short example:
{ // main of func
std::ios_base::fmtflags oldFlg =
cout.setf(std::ios_base::fixed, std::ios::floatfield);
int OutPre = cout.precision(40); // save prec, change to 40
// ------- use it here
// Case2Com Case2;
// Case2.execute(cout);
// -------
cout.setf( oldFlg, std::ios::floatfield ); // reset what you need
cout.precision( OutPre ); // restore orig precision
}
Here you pay another price, you need to 'reset' everything you changed.

This doesn't solve the problem. What happens if there is an
exception when you are using it? I thought everyone used RAII
here, and had their own SaveFormat or whatever class, so that
you'd write:

SaveFormat saver( std::cout ) ;
// whatever...

and when the destructor of saver was called, the original format
would be restored.

It's probably also worth pointing out that it is relatively
simple to use classes as manipulators, and restore the format in
their destructor. And of course, that in general, you don't use
the standard manipulators much in application code anyway; you
define your own, with application specific semantics, and do
logical formatting, instead of physical. (That way, when
someone decides that you need to output an additional digit in
degrees, you just change the manipulator for degrees, rather
than having to find which setprecision in you code refer to
degrees, and which don't.)

I have examples of both IOSave (a very, very old format saver)
and some useful manipulators (FFmt, EFmt and HexFmt) which
restore state at the end of the full expression at my site
(http://kanze.james.neuf.fr/code-en.html; the above mentionned
classes are in the IO subsystem).
 
B

BobR

/* """
What Pete said.
But, for a few dollars more, there is another way:
{ // scope1
std::eek:stringstream sos;
sos << hex << x << endl; // hex
cout << sos.str() <<endl;} // scope1
Now you are not changing std::cout.

That's definitly the most certain. On the other hand, it's a
lot of extra effort, and rather heavy and cumbersome.
"" */

Hi James,

You say "heavy and cumbersome", I said "a few dollars more". <G>
( ever pay for those extended warrenties at Circuit City? ever need them?
:-} )
[ Circuit City is an electronics store who "push" customers to buy extra
protection. Have them in France (yet)? ]

/* ""
In case you can't do that, here is a short example:
{ // main of func
std::ios_base::fmtflags oldFlg =
cout.setf(std::ios_base::fixed, std::ios::floatfield);
int OutPre = cout.precision(40); // save prec, change to 40
// ------- use it here
cout.setf( oldFlg, std::ios::floatfield ); // reset what you need
cout.precision( OutPre ); // restore orig precision
}
Here you pay another price, you need to 'reset' everything you changed.

This doesn't solve the problem. What happens if there is an
exception when you are using it? I thought everyone used RAII
here, and had their own SaveFormat or whatever class, so that
you'd write:
SaveFormat saver( std::cout ) ;
// whatever...
and when the destructor of saver was called, the original format
would be restored.
""" */

Really hard for a 'newbie' to write a super-duper manipulator class if you
don't know the basics of the streams.
Example:
Hey, OP, do you know what "RAII" is? Exceptions? 'pass by value' vs. 'pass
by reference'?

Maybe he/she knows them, but I couldn't tell from the original post.

I am certainly not arguing with you (who be WAY up the mountain from me).
Just attempting to give my logic in answering the OP. <G>
[ I posted part of my early 'tests'.]

To OP: always listen to 'The Kanze'. If James says something questionable,
you'll see a very long thread of discussion following! <G>
 
B

barcaroller

BobR said:
Hey, OP, do you know what "RAII" is? Exceptions? 'pass by value' vs.
'pass
by reference'?
To OP: always listen to 'The Kanze'. If James says something questionable,
you'll see a very long thread of discussion following! <G>

Thank you both for your very useful responses. Yes, I am familiar with the
C++ concepts mentioned above and in fact I have written my own manipulators
in the past. I just needed to know if there was a way to use the standard
manipulators as described in my first posting.
 
S

sebor

When I use an iostream manipulator in a cout statement, it seems to affect
all subsequent cout statements.

cout << x << endl; // dec by default
cout << hex << x << endl; // hex
cout << x << endl // still hex

Is there a way I can have manipulators affect only the "current" cout
statement?

Not without writing a bit of code. Here's a simple example
implementation
of such a manipulator in the Apache C++ Standard Library:
http://svn.apache.org/repos/asf/incubator/stdcxx/trunk/examples/manual/fmtflags_manip.cpp

Note that simple user-defined manipulators depend on an implementation
defined type referred to as "smanip" and thus aren't necessarily
portable.
With more effort it is possible to write one's own manipulators that
are
completely portable, but I didn't go that far in the example.
 
J

James Kanze

[...]
Really hard for a 'newbie' to write a super-duper manipulator class if you
don't know the basics of the streams.
Example:
Hey, OP, do you know what "RAII" is? Exceptions? 'pass by value' vs. 'pass
by reference'?

A newbie asking a question here presumably wants to learn. What
bothers me most is the number of experienced programmers who
don't know how to right a manipulator. Or perhap rather, who
don't know when they should write one.
Maybe he/she knows them, but I couldn't tell from the original post.

Yes. My goal here was just to throw out ideas. After that, the
original poster can adopt his own policies, according to his
level (but hopefully, he will be stimulated to find out about
RAII). (I know of at least one very competent programmer who
solves the problem by always setting everything, i.e.:
std::cout << std::dec << i ;
systematically. That's also a solution.)
I am certainly not arguing with you (who be WAY up the mountain from me).
Just attempting to give my logic in answering the OP. <G>

I wasn't complaining about your solution; I use it myself often
enough. I just thought it worth pointing out that there are
really a lot of solutions (and no one right answer).
 
B

BobR

James Kanze said:
I just thought it worth pointing out that there are
**really a lot of solutions (and no one right answer).**

(In C++,) IMHO, that is a big understatement! <G>
[ ....considering some/many compilers have 'asm'. [1] ]

Thanks James.

- -
Bob R
POVrookie
[1] Weird - I came to C++ from Assembler (in 2000), and I've never even
tried 'asm' in C++! <G> (never found a good reason to.).
 
S

sebor

When I use an iostream manipulator in a cout statement, it seems to affect
all subsequent cout statements.

cout << x << endl; // dec by default
cout << hex << x << endl; // hex
cout << x << endl // still hex

Is there a way I can have manipulators affect only the "current" cout
statement?

Not without writing a bit of code. Here's a simple example
implementation
of such a manipulator in the Apache C++ Standard Library:
http://svn.apache.org/repos/asf/incubator/stdcxx/trunk/examples/manual/fmtflags_manip.cpp

Note that simple user-defined manipulators depend on an implementation
defined type referred to as "smanip" and thus aren't necessarily
portable.
With more effort it is possible to write one's own manipulators that
are
completely portable, but I didn't go that far in the example.
 

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

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,175
Latest member
Vinay Kumar_ Nevatia
Top