Как напечатать двойную букву с запятой
-
07-07-2019 - |
Вопрос
В C ++ у меня есть переменная с плавающей запятой / double .
Когда я печатаю это, например, с помощью cout, результирующая строка разделяется точкой.
cout << 3.1415 << endl
$> 3.1415
Есть ли простой способ принудительно напечатать double через запятую?
cout << 3.1415 << endl
$> 3,1415
Решение
imbue() cout
с помощью locale
чей numpunct
грани decimal_point()
функция-член возвращает запятую.
Получение такого 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>(',')));
Другие советы
Вам необходимо очистить поток с помощью другого языкового стандарта, в котором фасет num_punct (iirc) указывает запятую.
Если локаль вашей платформы форматируется запятыми, то
cout.imbue(locale(""));
должно быть достаточно.
Это зависит от локали вашей программы. Р>
Способ установки языка программы по умолчанию зависит от платформы. На платформах типа POSIX, например, с переменными среды LANG и LC_ *. Р>
Вы можете принудительно настроить конкретную локаль - отличную от заданной по умолчанию - в программе на C ++, вызвав ios :: imbue. Примерно так может работать:
#include <locale>
cout.imbue(std::locale("German_germany"));
Идея состоит в том, чтобы заставить язык, в котором запятая является десятичным разделителем. Возможно, вам придется настроить & Quot; German_germany & Quot; строка, чтобы получить желаемое поведение на вашей конкретной платформе.
Если быть точным, это контролируется значением std::numpunct<charT>::decimal_point()
. Вы можете imbue()
другой язык с другим decimal_point()
Старый поток, но, в любом случае ... Следует помнить, что использование 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 " во второй выходной строке она неразрывная, что делает строку еще красивее: -)
Очень старая ветка, но в любом случае ... У меня была проблема с заполнением текстовой записи под 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());