Преобразование строки формата C в манипуляторы C ++ io - PullRequest
0 голосов
/ 04 мая 2011

В C я использую printf ("% + 10.5d \ n", x); вывести целое число x.

Я написал небольшой тестовый пример для манипуляторов C ++ io, но вывод имеет другой формат:

#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;
}

Вывод:

./testcommand
       +00003
           +3

Какой io-манипулятор мне здесь не хватает, чтобы получить тот же вывод, что и с printf?

Ответы [ 4 ]

2 голосов
/ 04 мая 2011

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

с коротким оператором if
((x>0) ? "+" : "" )

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

1 голос
/ 04 мая 2011

Используя boost :: 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;
}

Для функции sprintf вы можете изменить строку cout на эту.

std::string x_string = boost::str(boost::format("%+10.5d") % x);
0 голосов
/ 04 мая 2011

В данном конкретном случае я не думаю, что это возможно, по крайней мере, без большой работы.В C ++ (в отличие от C) аргумент precision игнорируется при выводе целого числа, поэтому вы не можете получить желаемый эффект, используя только манипуляторы (и boost::format также не поддерживает его).Вам, вероятно, придется отформатировать строку, затем поставить префикс или вставить '0' вручную.

В прошлом у меня был класс GB_Format (это были дни до пространства имен), что-то вродеboost::format, но который поддерживает все спецификации форматирования Posix;чтобы заставить "%.<i>n</i>d" работать, мне пришлось самому выполнять интегральные преобразования, а не использовать базовые преобразования потоков.Примерно так:

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() );
}
0 голосов
/ 04 мая 2011

Самое близкое, что я могу получить, это (обратите внимание на 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;
}

, что все еще не совсем верно:

    +00003
+000000003

, но это улучшение.

...