как усечь ширину целочисленных типов с std :: ostringstream? - PullRequest
2 голосов
/ 15 декабря 2010

Скажем, у вас есть что-то вроде:

std::ostringstream oss;
int value(42);
oss.fill('0');
oss << std::setw(3) << value;
cout << oss.str();

ВЫХОД: 042

Это вывод, потому что std :: setw обеспечивает минимальную ширину, и мы сказали потоку заполнить 0, однако как вы делаете обратное и задаете максимальную ширину, чтобы отображение было усечено в STL и предпочтительно в собственном C ++ .. .

В настоящее время у меня есть кое-что, что я считаю уродливым и неэффективным взломом:

std::ostringstream oss;
int value(1239999);
oss.fill('0');
oss << std::setw(3) << boost::lexical_cast<std::string, int>(value).substr(0, 3);
cout << oss.str();

ВЫХОД: 123

Я смотрел на boost :: format, но там такая же история, насколько я могу судить, что нет способа сделать это "красиво" ... есть предложения?

UPDATE: потоки std :: ostringstream и STL в целом, как известно, работают медленнее по сравнению с другими контейнерами и шаблонными объектами STL. Возможно, мне было бы лучше создать объект очереди сообщений, который обертывает и внутренне использует std :: queue, а затем просто использует sprintf_s для форматирования?

Ответы [ 2 ]

3 голосов
/ 15 декабря 2010

Усечение для удаления значащих цифр "осуждается" большинством современных программистов. В старые добрые времена форматирования на Фортране было довольно распространенным получить результат вроде

Total Sales
-----------
9,314,832.36
1,700,328.04
*,***,***,**
8,314,159.26
...

Даже современный Excel Excel попадает в эту ловушку с показателем переполнения ширины поля ########

Если выводимое число не вписывается в ширину поля, текущая философия заключается в том, чтобы нарушить границы ширины поля и надежно отобразить значение. Единственным недостатком будет то, что программа на Фортране будет считывать ввод (таким образом, ожидая строгого использования столбцов).

0 голосов
/ 15 декабря 2010

Возможности форматирования потока не предназначены в качестве универсального пакета для работы со строками.То, что вы пытаетесь сделать, не имеет большого смысла в численном отношении, поэтому оно не поддерживается - использование подстроки или аналогичных функций - это путь.Вы можете (и должны, если вам это нужно более чем в одном месте) написать свою собственную функцию для выполнения работы.

Что-то вроде:

#include <iostream>
#include <sstream>
#include <string>
#include <iomanip>

void First3( std::ostream & os, int value ) {
    std::ostringstream oss;
    oss.fill('0');
    oss << std::setw(3) << value;
    os << oss.str().substr( 0, 3 );
}

int main() {
    First3( std::cout, 1239999 );
    std::cout << " ";
    First3( std::cout, 1 );
}

Обратите внимание, что нет необходимости в Boostбудет использоваться.

...