PeterK
PeterK

Reputation: 6317

How to preserve formatting for C++ streams?

I have the following code (simplified):

ostringstream oss;

oss << "Text ";

oss << hex << uppercase;
oss.width(8);
oss.fill('0');

oss << var1 << " ";
oss << var2 << " ";

oss << dec << nouppercase;
oss.width(1);

oss << var3 << " another text." << endl;

string result = oss.str();
// work with result...

Where var1, var2 are unsigned int's and var3 is an int. The idea is to create a string where var1 and var2 are formated like a hex number (but without the 0x) and var3 as a regular integer. What i found out that only the first number is correctly formated, the second one is not padded with zeroes:

Text 000AF00C 3B7FF 1 another text.

After a while i found out that setting the width and fill parameters AGAIN fixes this. Is there a way how to avoid specifying these formating rules over and over again for each number? The amount of formatted variables is much higher than 2, this was just a simplified example. Wrapping all this into a function is an option, but i would really like to learn how to preserve the formatting with ostringstream.

Upvotes: 1

Views: 377

Answers (4)

CB Bailey
CB Bailey

Reputation: 791849

All your format settings should be preserved except for width which is only preserved until the next formatted output operation. This is because formatted output functions are required to call width(0) as a side effect.

A reasonably succinct solution would be to use the setw manipulator before the output operations that require a non-zero width.

Note that you might be surprised at the output for this if you've set the fill character and a width of 8 was preserved from the last numeric output.

os << " ";

Upvotes: 0

sbi
sbi

Reputation: 224069

Is there a way how to avoid specifying these formating rules over and over again for each number?

No, there are manipulators which are sticky and there are those which are not. Those that are not have to be repeated for every output.

BTW, you can apply some syntactic sugar and turn

oss.width(8);
oss.fill('0');

oss << var1 << " ";

into

oss << std::setw(8) << std::setfill('0') << var1 << " ";

Upvotes: 3

anon
anon

Reputation:

As always, write a function:

void WriteHex( unsigned int n, ostream & os  ) {
  os << hex << uppercase;
  os.width(8);
  os.fill('0');
  os << n;
}

Upvotes: 1

codymanix
codymanix

Reputation: 29468

Sorry some settings for stream formatting are called volatile (has nothing to do with the keyword), you have to set it each time. See here for explanation.

It will be best to create your own functions.

Upvotes: 4

Related Questions