Pregunta

En C ++ tengo una variable flotante / doble.

Cuando imprimo esto con, por ejemplo, cout, la cadena resultante está delimitada por puntos.

cout << 3.1415 << endl
$> 3.1415

¿Hay alguna manera fácil de forzar que el doble se imprima con una coma?

cout << 3.1415 << endl
$> 3,1415
¿Fue útil?

Solución

imbue() cout con un locale cuya función de miembro numpunct faceta decimal_point() devuelve una coma.

La obtención de tal std::locale("fr") se puede hacer de varias maneras. Podría usar una configuración regional con nombre disponible en su sistema (do_decimal_point(), tal vez). Alternativamente, podría derivar su propio numpuct, implementar el <=> miembro en él.

Ejemplo del segundo enfoque:

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

Utilizado como:

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

Otros consejos

Debe imponer a la secuencia una configuración regional diferente, una cuya faceta num_punct (iirc) especifique una coma.

Si su plataforma localiza formatos con comas, entonces

cout.imbue(locale(""));

debería ser suficiente.

Esto está controlado por la configuración regional de su programa.

La forma en que configura la configuración regional predeterminada de un programa depende de la plataforma. En plataformas de tipo POSIX, es con las variables de entorno LANG y LC_ *, por ejemplo.

Puede forzar un entorno local particular, diferente del predeterminado, dentro de un programa C ++ llamando a ios :: imbue. Algo como esto podría funcionar:

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

La idea es forzar un entorno local donde la coma es el separador decimal. Es posible que deba ajustar & Quot; German_germany & Quot; cadena para obtener el comportamiento que desea en su plataforma particular.

Para ser precisos, esto se controla mediante el valor std::numpunct<charT>::decimal_point(). Puede imbue() otra configuración regional con otra decimal_point()

Hilo antiguo, pero de todos modos ... Uno debe tener en cuenta que el uso de un std::locale hace que la cadena " bonita " ;, se complete con el punto decimal correcto, miles de separadores y qué no, dependiendo de La plataforma y el local. Lo más probable es que el uso de imbue() interrumpa cualquier análisis de la cadena después de formatearla. Por ejemplo:

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

Da el siguiente resultado:
without locale: 1234.56
with fr locale: 1 234,56

Usar strtod() o similar en la segunda cadena probablemente no funcionará muy bien ... Además, el espacio entre " 1 " y " 2 " en la segunda cadena de salida no se rompe, lo que hace que la cadena sea aún más bonita :-)

Hilo muy antiguo, pero de todos modos ... Tuve el problema de llenar una entrada de texto en Gtkmm-3.0 con el resultado de un cálculo de distancia. Para aclarar las cosas, agrego un ejemplo, donde he concentrado algunas sabidurías de varias publicaciones que leí los últimos días:

#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());
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top