Десятичные точки с помощью std::stringstream?

У меня есть куча целых чисел, которые я положил в stringstreams. Теперь я хочу изменить stringstreamс в stringс сохранением постоянной точности с strings. Как бы я это сделал? Я знаю, что могу использовать stringstreams.precision(), но по какой-то причине это не работает:

float a = 5.23;
float b = 3.134;
float c = 3.0;

std::stringstream ta;
std::stringstream tb;
std::stringstream tc;

ta << a;
tb << b;
tc << c;

ta.precision(2);
tb.precision(2);
tc.precision(2);

std::string out = "";
out += ta.str() + "\n";
out += tb.str() + "\n";
out += tc.str() + "\n";

Вернусь 5.23\n3.134\n3.0, скорее, чем 5.23\n3.13\n3.00

3 ответа

Я думаю, что ваша проблема в том, что precision() устанавливает точность, используемую в будущих операциях вставки потока, а не при генерации последней строки для представления. То есть, написав

ta << a;
tb << b;
tc << c;

ta.precision(2);
tb.precision(2);
tc.precision(2);

Вы устанавливаете precision слишком поздно, поскольку первые три строки уже преобразовали числа с плавающей запятой в строки, используя точность по умолчанию.

Чтобы это исправить, попробуйте изменить порядок выполнения этих операторов на

ta.precision(2);
tb.precision(2);
tc.precision(2);

ta << a;
tb << b;
tc << c;

Это приведет к записи в stringstream использовать вашу пользовательскую точность, а не существующие значения по умолчанию.

Тем не менее, эффект от precision Модификатор имеет смысл только в том случае, если вы явно указываете потоку, что вы хотите использовать для вывода либо фиксированную точность, либо научную нотацию. Для этого вы можете использовать либо fixed или же scientific модификаторы:

ta.precision(2);
tb.precision(2);
tc.precision(2);

ta << fixed << a;
tb << fixed << b;
tc << fixed << c;

Это будет правильно отображать соответствующее количество цифр.

На связанной ноте, вам не нужно использовать три stringstreamдля достижения вашей цели. Вы можете просто использовать один:

std::stringstream t;
t.precision(2);

t << fixed << a << '\n' << b << '\n << c << '\n';

std::string out = t.str();

В С++ 20 вы можете использовать, который эффективен и менее многословен, чем std::stringstream:

      float a = 5.23;
float b = 3.134;
float c = 3.0;
std::string out = std::format("{:.2f}\n{:.2f}\n{:.2f}\n", a, b, c);

А пока вы можете использовать библиотеку {fmt} , основанную на ( godbolt ).

Отказ от ответственности : я автор {fmt} и C++20. std::format.

Вам нужно установитьfixedа такжеprecisionперед подачей данных в stringstream. Вот рабочий пример того, что вы намеревались сделать:

      #include <iostream>
#include <sstream>

using namespace std;

int main(){
    float a = 5.23;
    float b = 3.134;
    float c = 3.0;

    std::stringstream ss;
    ss.setf(std::ios::fixed);
    ss.precision(2);
    
    ss << a << "\n";
    ss << b << "\n";
    ss << c << "\n";
    cout<<ss.str()<<endl;

    return 0;
}

выход:

      5.23
3.13
3.00
Другие вопросы по тегам