3

I know this question has been asked before but in a bunch of different contexts which I could not really understand(as I am new to the c++ language,previously from java). My question related to std::fixed and setprecision() in iomanip.

I have the following simple double:

double price = 7.50001;

With this I wanted it to output as per a normal price as so:

cout<< "The price is:$" <<fixed<<setprecision(2)<< price <<endl;

However now due to std::fixed every cout I use from now on will have precision(2). My question is how do I roll back to the previous precision that is if I add another double say 6.5100000 the output will be 6.5, a double such as 6.200000 will be 6.2, 6.15555 will be 6.15555 etc. (as per before).

Note I have tried using this as per google:

std::streamsize ss = std::cout.precision();

... And then resetting the precision using ss, however this does not work as the output still includes trailing zeros which it did not before. For example 6.50 outputs 6.50 when before it output 6.5 (this is true for any double previously,it eliminated trailing zeros).

YSC
  • 38,212
  • 9
  • 96
  • 149
JmanxC
  • 377
  • 2
  • 16
  • 1
    You can always [get the previous precision](http://en.cppreference.com/w/cpp/io/ios_base/precision), and use it to reset. – Some programmer dude Sep 16 '17 at 22:03
  • Possible [duplicate](https://stackoverflow.com/questions/7422200/whats-the-opposite-of-fixed-in-cout) – Mikael Sep 16 '17 at 22:04
  • I have tried using that approach however given double 7.50001 for example and using cout.precision(2) then outputting the double it gives me 7.5 instead of 7.50, which is not what shows in the example under that url. – JmanxC Sep 16 '17 at 22:20
  • int previousPrecision = cout.precision(); cout<<"Initial Precision: " << previousPrecision< – JmanxC Sep 16 '17 at 22:21
  • Protip: iostream's approach to formatting is ugly, confusing and verbose, a huge step back compared to C's `printf` (and to name-whatever-other-language's placeholder-based formatting), and, as you noticed, the stateful formatters are a nightmare. If you want to do vaguely elaborated formatting without getting mad, use C's `printf`-family functions: this whole conundrum gets resolved as `printf("The price is: $%0.2f\n", price);`. The difference in clarity (and the lack of state-related problems) is so stunning that it needs no comments. – Matteo Italia Sep 16 '17 at 22:27
  • I may take that approach as it is closer to how I usually do it in java. This state approach is indeed a nightmare – JmanxC Sep 16 '17 at 22:38
  • Also, unless you know you need to flush the output buffer don't get in the habit of using `endl` - if forces a flush of the output buffer, which degrades the performance significantly when outputting to file (even if you are using `cout`, it may be redirected to file); just use `\n`, it'll do the right thing in virtually all the "normal" situations (stdout is already line-buffered when working on a console and is tied to stdin, so it already flushes when asking for user input). – Matteo Italia Sep 16 '17 at 22:40

3 Answers3

2

According to what I understood you want to print doubles with different format, this would be done several times to cout, but with different precision specifiers:

    std::streamsize defaultprecision = std::cout.precision(); // save default precision    
    std::cout.precision(1); // change default precision
    cout << std::fixed; // enable fixed
    double price = 6.5100000;
    cout<< "The price is:$" << price <<endl;
    price = 6.200000;
    cout<< "The price is:$" << price <<endl;

    std::cout.unsetf ( std::ios::fixed );  // disable fixed     
    std::cout.precision(defaultprecision); // restore default presicion

    price = 6.15555;
    cout<< "The price is:$" <<price <<endl;

Output:

6.5
6.2
6.15555
yacsha
  • 71
  • 4
  • Ah unsetf is exactly what i was looking for, thank you!! – JmanxC Sep 16 '17 at 22:48
  • I have reviewed and corrected my previous response because I think I did not understand what you were looking for. You were referring to resetting the fixed and the precision, this is achieved with std :: cout.precision and std :: cout.unsetf, respectively. – yacsha Sep 16 '17 at 22:49
1

most convenient would be, I think, to simply save all format flags and reset them.

double price = 6.511111;

std::ios  state(NULL);
state.copyfmt(std::cout);
std::cout << "The price is:$" << std::fixed << std::setprecision(2)<< price << std::endl;
std::cout.copyfmt(state);
std::cout << "The price is:$" << price << std::endl;

Output:

The price is:$6.51
The price is:$6.51111

Edit: If you need that often it might be an option to make class for this and handle resetting the flags in the destructor, but for your simple example that would be a little bit over the top it seems.

DrSvanHay
  • 1,170
  • 6
  • 16
  • hmm I ran into an issue with this as well. For example before the std:setprecision line, doubles such as 6.5111 would output as so and any double with trailing zeros would be eliminated(for example 6.10000 would be 6.1 but 6.000001 would remain so in output). However now with that code if i were to use a double such as 6.511111 it would make it 6.5 after resetting the flags. What i require if possible is a way to change the state of cout to what it was before the line with fixed and setprecison was used. – JmanxC Sep 16 '17 at 22:32
  • @JmanxC Ah now I understand. Sorry. I´ve edited the answer accordingly. – DrSvanHay Sep 16 '17 at 22:57
0

You can define a reset mechanism by yourself:

#include <iostream>
#include <iomanip>

namespace format
{
    class reset_type
    {
        std::ios state;
    public:
        reset_type() : state(nullptr) { state.copyfmt(std::cout); }
        friend std::ostream& operator<<(std::ostream& os, reset_type& r)
        {
            os.copyfmt(r.state);
            return os;
        }
    } reset;
}

int main()
{
    const double price = 6.511111;
    std::cout << "The price is: $" << std::fixed << std::setprecision(2) << price << "\n"
              << format::reset << "The price is: $" << price << "\n";
}

Demo

Output:

The price is: $6.51
The price is: $6.51111
YSC
  • 38,212
  • 9
  • 96
  • 149