4

I am using setf in for displaying decimal places in outputs.

cout.setf(ios::fixed);
cout.setf(ios::showpoint);
cout.precision(2);

However, when I put the above code before an output, other outputs are affected too. Is there any way I can use setf for just only a single output? Like turning it off?

Thank you a lot!

bffaf02
  • 43
  • 3

3 Answers3

6

setf returns the original flag value, so you can simply store that then put it back when you're done.

The same is true of precision.

So:

// Change flags & precision (storing original values)
const auto original_flags     = std::cout.setf(std::ios::fixed | std::ios::showpoint);
const auto original_precision = std::cout.precision(2);

// Do your I/O
std::cout << someValue;

// Reset the precision, and affected flags, to their original values
std::cout.setf(original_flags, std::ios::fixed | std::ios::showpoint);
std::cout.precision(original_precision);

Read some documentation.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
2

You can use flags() method to save and restore all flags or unsetf() the one returned by setf

 std::ios::fmtflags oldFlags( cout.flags() );

 cout.setf(std::ios::fixed);
 cout.setf(std::ios::showpoint);
 std::streamsize oldPrecision(cout.precision(2));

 // output whatever you should.

 cout.flags( oldFlags );
 cout.precision(oldPrecision)
Swift - Friday Pie
  • 12,777
  • 2
  • 19
  • 42
  • This is wrong; interjay explained why in my answer. Not really sure why you copied my answer half an hour later anyway – Lightness Races in Orbit Jan 21 '17 at 19:35
  • @Lightness Races in Orbit not sure what you mean. cout.flags() use is kind of snippet we use around. and we were answering practically at same time. all interjay said, that setf #1 can't unset flags and that's right. might be an over engineered solution, pretty much same if you was tracking flags on your own. – Swift - Friday Pie Jan 22 '17 at 15:26
  • No, you need to set the flag mask if you want to _remove_ flags. I made the same mistake, and interjay set me straight. Read his comment and my edited answer. – Lightness Races in Orbit Jan 22 '17 at 15:29
  • 1
    @Lightness Races in Orbit no, you don't need that with flags(). flags() #1 got no parameters then it returns current state of fmtflags of stream, flags() #2 got one parameter and it sets fmtflags of stream to that value exactly, overwriting old values: http://www.cplusplus.com/reference/ios/ios_base/flags/ If you think that it is too much, check implementation of setf(fmtfl, mask): flags((fmtfl&mask)|(flags()&~mask)). – Swift - Friday Pie Jan 22 '17 at 15:37
1

Your problem is that you share the formatting state with someone else. Obviously you can decide to track the changes and to correct them. But there is a saying: The best way to solve a problem is to prevent it from happening.

In your case, you need to have your own formatting state and to not share it with anyone else. You can have your own formatting state by using an instance of std::ostream with the same underlying streambuf than std::cout.

std::ostream my_fmt(std::cout.rdbuf());
my_fmt.setf(std::ios::fixed);
my_fmt.setf(std::ios::showpoint);
my_fmt.precision(2);

// output that could modify fmt flags
std::cout.setf(std::ios::scientific);
std::cout.precision(1);
// ----

// output some floats with my format independently of what other code did
my_fmt << "my format: " << 1.234 << "\n";
// output some floats with the format that may impacted by other code
std::cout << "std::cout format: " << 1.234 << "\n";

This will output:

my format: 1.23
std::cout format: 1.2e+00

See a live example there: live

fjardon
  • 7,921
  • 22
  • 31