Усечение строковых полей C ++, сгенерированных ostringstream, iomanip: setw - PullRequest
2 голосов
/ 25 мая 2010

В C ++ мне нужны строковые представления целых чисел с ведущими нулями, где представление имеет 8 цифр и не более 8 цифр, при необходимости обрезая цифры с правой стороны. Я думал, что смогу сделать это, используя только ostringstream и iomanip.setw (), вот так:

int num_1 = 3000;
ostringstream out_target;

out_target << setw(8) << setfill('0') << num_1;
cout << "field: " << out_target.str() << " vs input: " << num_1 << endl;

Вывод здесь:

field: 00003000 vs input: 3000

Очень мило! Однако, если я попытаюсь увеличить число, setw позволит выводить больше 8 символов:

int num_2 = 2000000000;
ostringstream out_target;

out_target << setw(8) << setfill('0') << num_2;
cout << "field: " << out_target.str() << " vs input: " << num_2 << endl;
out_target.str("");

выход: * +1010 *

field: 2000000000 vs input: 2000000000

Требуемый выход «20000000». Ничто не мешает мне использовать вторую операцию, чтобы взять только первые 8 символов, но действительно ли в iomanip отсутствует усечение поля? Будет ли форматирование Boost делать то, что мне нужно, за один шаг?

Ответы [ 2 ]

2 голосов
/ 25 мая 2010

Я не могу придумать способ обрезать числовое поле таким образом. Возможно, это не было реализовано, потому что это изменило бы значение.

ostream::write() позволяет достаточно просто обрезать буфер string , как в этом примере ...

    int num_2 = 2000000000;
    ostringstream out_target;

    out_target << setw(8) << setfill('0') << num_2;
    cout << "field: ";
    cout.write(out_target.str().c_str(), 8);
    cout << " vs input: " << num_2 << endl;
1 голос
/ 25 мая 2010

Если вы предполагаете, что snprintf () напишет как можно больше символов (я не думаю, что это гарантировано),

char buf[9];
snprintf(buf, 10, "%08d", num);
buf[8] = 0;
cout << std::string(buf) << endl;

Я не уверен, почему вы хотите, чтобы 2 миллиарда былотак же, как 20 миллионов.Может иметь больше смысла сигнализировать об ошибке усечения, например:

if (snprintf(buf, 10, "%08d", num) > 8) {
    throw std::exception("oops")
}
...