I am using std::ostringstream to format a double to a string with a specific format (using apostrophes as thousands separators). However, in some cases ostringstream gave me a different result from what I expected.
As far as I can tell, the expected output of the code below should be "+01"; instead it outputs "0+1". What am I doing wrong here, and how can I get the result I need?
#include <iomanip>
#include <iostream>
#include <sstream>
int main()
{
std::ostringstream stream;
stream << std::showpos; // Always show sign
stream << std::setw(3); // Minimum 3 characters
stream << std::setfill( '0' ); // Zero-padded
stream << 1; // Expected output: "+01"
std::cout << stream.str(); // Output: "0+1"
return 0;
}
Code on ideone
There are three options for the padding, left
, right
, and internal
.
You want internal
padding, between the sign and the value.
stream << std::setfill( '0' ) << std::internal; // Zero-padded
You can use std::internal
juste before std::showpos
(as shown here).
We need to add the std::internal flag to tell the stream to insert "internal padding" -- i.e., the padding should be inserted between the sign and the rest of the number.
#include <iomanip>
#include <iostream>
#include <sstream>
int main()
{
std::ostringstream stream;
stream << std::setfill('0');
stream << std::setw(3);
stream << std::internal;
stream << std::showpos;
stream << 1;
std::cout << stream.str(); // Output: "+01"
return 0;
}
The fill character is used with any type to fill a given width. By default the fill characters go to the left of the value, and that’s what you’re seeing with those zeros. The solution is to override that default and tell the stream to put the fill characters inside the text:
std::cout << std::internal << std::setfill(0) << std::setw(3) << 1 << '\n';
You can also use std::left
or std::right
to put the fill characters on the left of the value or the right of the value.
That is, unfortunately, how it is supposed to work. The '0' is used as a fill character, not as a part of the number.
To fix it, you must output the + or - separately:
std::ostringstream oss;
oss << "+-"[x<0];
oss << std::setw(2) << std::setfill('0') << std::abs(x);
return/cout/whatever oss.str();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With