Resetting std::stringstream format flags

2.4k views Asked by At

I need to print hex and decimal values in my console. I used the following piece of code to do it.

std::stringstream ss;

ss << "0x" << std::uppercase << std::hex << 15;    
std::cout << ss.str() << std::endl;

ss.str("");
ss.clear();

ss << 15;
std::cout << ss.str() << std::endl;

But I am getting both values in Hex format. How to reset stringstream?

3

There are 3 answers

0
πάντα ῥεῖ On BEST ANSWER

How to reset stringstream?

Format flags are sticky.

You can save the old format flags to restore them later:

std::stringstream ss;
auto oldFlags = ss.flags(); // <<

ss << "0x" << std::uppercase << std::hex << 15;    
std::cout << ss.str() << std::endl;

ss.flags(oldFlags); // <<

ss << 15;
std::cout << ss.str() << std::endl;
0
Dietmar Kühl On

Assuming you know which formatting flag are actually used, you can just save their original value and restore them later. When the set of formatting flags being changed is large and possibly somewhat out of the control of the function, there are essentially two approaches which are both, unfortunately, not really very cheap:

  1. Do not use the std::stringstream directly but rather use a temporary stream to which the format flags get applied:

    {
        std::ostream out(ss.rdbuf());
        out << std::showbase << std::uppercase << std::hex << 15;
    }
    ss << 15;
    
  2. You can use the copyfmt() member to copy all the formatting flags and later restore these:

    std::ostream aux(0); // sadly, something stream-like is needed...
    out.copyfmt(ss);
    out << std::showbase << std::uppercase << std::hex << 15;
    ss.copyfmt(aux);
    out << 15;
    

Both approaches need to create a stream which is, unfortunately, not really fast due to a few essentially mandatory synchronizations (primarily for creating the std::locale member).

0
Տիգրան Խաչակրանց On

Just use

std::nouppercase

ss << std::uppercase;    
...

ss << std::nouppercase;

...