Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ostream: prefix a positive number with a space

Tags:

c++

In C a space can be included in a printf formatting flag which results in positive numbers being prefixed with a space. This is a useful feature for aligning signed values. I can't figure out how to do the same in C++. In C:

double d = 1.2;
printf("%f\n",d);
printf("%+f\n",d);
printf("% f\n",d);

produces:

1.2
+1.2
 1.2

Using ostream, I can do the first two, but how do I do the third?

int d = 1.2;
std::cout << d << std::endl;
std::cout << std::showpos << d << std::endl;
// ??????????????

EDIT: There seems to be some confusion about whether or not I just want to prefix all of my values with a space. I only want to prefix positive values with a space, similar to a) like the printf space flag does and b) similar to what showpos does, except a space rather than a '+'. For example:

printf("%f\n", 1.2);
printf("%f\n", -1.2);
printf("% f\n", 1.2);
printf("% f\n", -1.2);

1.2
-1.2
 1.2
-1.2

Note that the third value is prefixed with a space while the fourth (negative) value is not.

like image 634
J.Kraftcheck Avatar asked Oct 04 '12 13:10

J.Kraftcheck


4 Answers

You can use setfill and setw, like this:

cout << setw(4) << setfill(' ') << 1.2 << endl;
cout << setw(4) << setfill(' ') << -1.2 << endl;

This produces the following output:

 1.2
-1.2

Don't forget to include <iomanip> in order for this to compile (link to ideone).

like image 78
Sergey Kalinichenko Avatar answered Nov 03 '22 03:11

Sergey Kalinichenko


I don't have my standard with me and I'm doing this stuff too rarely to be confident about it: There are two ingredients to achieving this with IOStreams:

  1. Use std:: showpos to have an indicator of positive values be shown. By default this will use +, of course.
  2. I think the + is obtained using std::use_facet<std::ctype<char> >(s.get_loc()).widen('+'). To turn this into a space you could just use a std::locale with a std::ctype<char> facet installed responding with a space to the request to widen +.

That is, something like this:

struct my_ctype: std::ctype<char> {
    char do_widen(char c) const {
        return c == '+'? ' ': this->std::ctype<char>::do_widen(c);
    }
};

int main() {
    std::locale loc(std::locale(), new my_ctype);
    std::cout.imbue(loc);
    std::cout << std::showpos << 12.34 << '\n';
}

(the code isn't tested and probably riddled with errors).

like image 23
Dietmar Kühl Avatar answered Nov 03 '22 03:11

Dietmar Kühl


How about

std::cout << (d >= 0 ? " ":"")  << d << std::endl;
like image 2
Luchian Grigore Avatar answered Nov 03 '22 03:11

Luchian Grigore


std::cout << " " << my_value;

If you need space only for positive:

if (my_value >=0 ) cout << " "; cout << my_value;
like image 1
Andrew Avatar answered Nov 03 '22 03:11

Andrew