Question

In C++ I've got a float/double variable.

When I print this with for example cout the resulting string is period-delimited.

cout << 3.1415 << endl
$> 3.1415

Is there an easy way to force the double to be printed with a comma?

cout << 3.1415 << endl
$> 3,1415
Was it helpful?

Solution

imbue() cout with a locale whose numpunct facet's decimal_point() member function returns a comma.

Obtaining such a locale can be done in several ways. You could use a named locale available on your system (std::locale("fr"), perhaps). Alternatively, you could derive your own numpuct, implement the do_decimal_point() member in it.

Example of the second approach:

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;
};

Used as:

std::cout.imbue(std::locale(std::cout.getloc(), new DecimalSeparator<char>(',')));

OTHER TIPS

You need to impue the stream with a different locale, one whose num_punct (iirc) facet specifies a comma.

If your platform locale formats with commas, then

cout.imbue(locale(""));

should be sufficient.

This is controlled by your program's locale.

How you set a program's default locale depends on the platform. On POSIX type platforms, it's with the LANG and LC_* environment variables, for instance.

You can force a particular locale -- different from the default -- within a C++ program by calling ios::imbue. Something like this might work:

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

The idea is to force a locale where comma is the decimal separator. You might need to adjust the "German_germany" string to get the behavior you want on your particular platform.

To be precise, this is controlled by the std::numpunct<charT>::decimal_point() value. You can imbue() another locale with another decimal_point()

Old thread, but anyway ... One should be aware that using a std::locale makes the string "pretty", complete with correct decimal point, thousands separators and what not, depending on the platform and locale. Most probably, using imbue() will break any parsing of the string after it's formatted. For example:

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();

Gives the following output:
without locale: 1234.56
with fr locale: 1 234,56

Using strtod() or similar on the second string probably won't work very well ... Also, the space between "1" and "2" in the second output string is a non-breaking one, making the string even prettier :-)

Very old thread, but anyway ... I had the problem to fill a text entry under Gtkmm-3.0 with the outcome of a distance calculation. To make things clearer I add an example, where I have concentrated some wisdoms of several posts I read the last days:

#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());
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top