Как напечатать двойной с запятой - PullRequest
9 голосов
/ 14 сентября 2009

В C ++ у меня есть переменная типа float / double.

Когда я печатаю это, например, cout, полученная строка разделяется точкой.

cout << 3.1415 << endl
$> 3.1415

Есть ли простой способ заставить двойник печататься через запятую?

cout << 3.1415 << endl
$> 3,1415

Ответы [ 6 ]

11 голосов
/ 14 сентября 2009

imbue() cout с locale, у которого numpunct функция-член *1003* facet возвращает запятую.

Получение такого locale может быть сделано несколькими способами. Вы можете использовать именованную локаль, доступную в вашей системе (возможно, std::locale("fr")). В качестве альтернативы, вы можете получить свой собственный numpuct, добавив в него член do_decimal_point().

Пример второго подхода:

template<typename CharT>
class DecimalSeparator : public std::numpunct<CharT>
{
public:
    DecimalSeparator(CharT Separator)
    : m_Separator(Separator)
    {}

protected:
    CharT do_decimal_point()const
    {
        return m_Separator;
    }

private:
    CharT m_Separator;
};

Используется как:

std::cout.imbue(std::locale(std::cout.getloc(), new DecimalSeparator<char>(',')));
3 голосов
/ 14 сентября 2009

Требуется очистить поток с помощью другого языкового стандарта, в котором фасет num_punct (iirc) указывает запятую.

Если локаль вашей платформы отформатирована запятыми, то

cout.imbue(locale(""));

должно быть достаточно.

2 голосов
/ 14 сентября 2009

Это зависит от локали вашей программы.

Способ установки локали программы по умолчанию зависит от платформы. На платформах типа POSIX, например, с переменными среды LANG и LC_ *.

Вы можете принудительно установить конкретную локаль - отличную от стандартной - в программе на C ++, вызвав ios :: imbue Примерно так может работать:

#include <locale>
cout.imbue(std::locale("German_germany"));

Идея состоит в том, чтобы форсировать локаль, в которой запятая является десятичным разделителем. Возможно, вам придется настроить строку «German_germany», чтобы получить поведение, которое вы хотите на вашей конкретной платформе.

1 голос
/ 14 сентября 2009

Если быть точным, это контролируется значением std::numpunct<charT>::decimal_point(). Вы можете imbue() другой язык с другим decimal_point()

0 голосов
/ 26 мая 2018

Очень старая тема, но в любом случае ... У меня была проблема, чтобы заполнить текстовую запись под Gtkmm-3.0 результатом вычисления расстояния. Чтобы прояснить ситуацию, я добавлю пример, где я сконцентрировал некоторые мудрости нескольких постов, которые я прочитал в последние дни:

#include <locale>
// next not necessary, added only for clarity
#include <gtkmm-3.0/gtkmm.h>
Gtk::Entry m_Text;
// a distance measured in kilometers
double totalDistance = 35.45678;
std::stringstream str;
// I am using locale of Germany, pay attention to the _
str.imbue(std::locale("de_DE"));
// now we have decimal comma instead of point
str << std::fixed << std::setprecision(4) << std::setw(16) << totalDistance << " km";
// the wished formatting corresponds to "%16.4f km" in printf
m_Text.set_text(str.str());
0 голосов
/ 03 декабря 2013

Старый поток, но в любом случае ... Следует помнить, что использование std::locale делает строку "красивой", с правильной десятичной точкой, разделителями тысяч и чем угодно, в зависимости от платформы и локали. Скорее всего, использование imbue() прервет любой разбор строки после ее форматирования. Например:

std::ostringstream s;
std::locale l("fr-fr");
s << "without locale: " << 1234.56L << std::endl;
s.imbue(l);
s << "with fr locale: " << 1234.56L << std::endl;
std::cout << s.str();

Дает следующий вывод:
without locale: 1234.56
with fr locale: 1 234,56

Использование strtod() или аналогичного значения во второй строке, вероятно, будет работать не очень хорошо ... Кроме того, пробел между «1» и «2» во второй выходной строке является неразрывным, что делает строку еще красивее: -)

...