Convert C format string to C++ io manipulators

1.2k Views Asked by At

In C, I'm using printf("%+10.5d\n", x); to print the integer x.

I've written a small test case for C++ io manipulators, but the output has a different format:

#include <iostream>
#include <iomanip>
#include <cstdio>

int main(void)
{
        int x = 3;
        printf("%+10.5d\n", x);
        std::cout << std::showpos << std::setw(10) << std::setprecision(5) << x << std::endl;
        return 0;
}

The output is:

./testcommand
       +00003
           +3

Which io manipulator I am missing here to get the same output as with printf?

4

There are 4 best solutions below

3
On

std::setfill
http://www.cplusplus.com/reference/iostream/manipulators/setfill/

with a short if statement
((x>0) ? "+" : "" )

so:
std::cout << ((x>0) ? "+" : "" ) << std::setfill('0') << std::setw(10) << std::setprecision(5) << x << std::endl;

1
On

The closest I can get is this (note the std::internal):

#include <iostream>
#include <iomanip>
#include <cstdio>

int main(void)
{
    int x = 3;
    printf("%+10.5d\n", x);
    std::cout << std::setfill('0') << std::internal << std::showpos << std::setw(10) << std::setprecision(5) << x << std::endl;
    return 0;
}

which is still not quite right:

    +00003
+000000003

but it's an improvement.

0
On

Using boost::format you can get what you're looking for in a more terse format.

http://www.boost.org/doc/libs/release/libs/format/doc/format.html

#include <boost/format.hpp>

int main(void)
{
    int x = 3;
    std::cout << boost::format("%+10.5d") % x << std::endl;
    return 0;
}

For sprintf functionality you could change the cout line to this.

std::string x_string = boost::str(boost::format("%+10.5d") % x);
0
On

In this particular case, I don't think it's possible, at least not without a lot of work. In C++ (unlike in C), the precision argument is ignored when outputting an integer, so you can't obtain the effect you want using just manipulators (and boost::format doesn't support it either). You'll probably have to format to a string, then prefix or insert the '0' manually.

In the past, I had a GB_Format class (this was pre-namespace days), a bit like boost::format, but which did support all of the Posix formatting specifications; in order to make "%.<i>n</i>d" work, I had to implement the integral conversions myself, rather than using the underlying stream conversions. Something like the following:

std::string
fmtInt( int value, int width, int precision )
{
    unsigned            work = (value < 0 ? -value : value);
    std::string         result;
    while ( work != 0 || result.size() < precision ) {
        result += "0123456789"[ work % 10 ];
        work /= 10;
    }
    result += (value < 0 ? '-' : '+');
    while ( result.size() < width ) {
        result += ' ';
    }
    return std::string( result.rbegin(), result.rend() );
}