2009-09-14 14 views
9

En C++ tengo una variable flotante/doble.Cómo imprimir un doble con una coma

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

cout << 3.1415 << endl 
$> 3.1415 

¿Hay una manera fácil de forzar el doble para ser impreso con una coma?

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

Respuesta

11

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

La obtención de tal locale se puede hacer de varias maneras. Puede usar una configuración regional con nombre disponible en su sistema (std::locale("fr"), quizás). Alternativamente, puede derivar su propio numpucto, implementar el miembro do_decimal_point() 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; 
}; 

utilizan como:

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

usando su ejemplo resultados en: std :: error de ejecución locale :: facet :: _ S_create_c_locale nombre no válido – NomeN

+0

Este error probablemente significa que, en su plataforma, el nombre "fr" no se vincula a una configuración regional. –

+0

Lo supuse todo, pero ¿cómo podría averiguar qué nombres * están * vinculados a una configuración regional? – NomeN

2

Esto se controla según la configuración regional de su programa.

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

Puede forzar una configuración regional concreta, diferente de la predeterminada, 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 una configuración regional donde coma es el separador decimal. Es posible que deba ajustar la cadena "German_germany" para obtener el comportamiento que desea en su plataforma particular.

+0

usando su ejemplo resultados en: std :: error error locale :: facet :: _ S_create_c_locale nombre no válido – NomeN

3

Debe implementar la secuencia con una configuración regional diferente, una cuya raíz num_punct (iirc) especifique una coma.

Si sus formatos de localización de plataforma con comas, después

cout.imbue(locale("")); 

deberían ser suficientes.

+0

t hx, tu respuesta funcionó. Pero me gustaría aceptar una respuesta que sea más genérica (si no tienes tanta suerte con la configuración preestablecida correcta en tu plataforma). Todavía +1 porque es el método más fácil. – NomeN

1

Para ser precisos, esto está controlado por el valor std::numpunct<charT>::decimal_point(). Puede imbue() otro local con otro decimal_point()

0

hilo viejo, pero de todos modos ... Uno debe ser consciente de que el uso de un std::locale hace que la cadena "bastante", completo con el punto decimal correcto, separadores de miles y lo que no, según la plataforma y la configuración regional. Lo más probable es que al usar imbue() se rompa cualquier análisis sintáctico 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

Usando strtod() o similares en la segunda cuerda probablemente no va a funcionar muy bien ... Además, el espacio entre "1 "y" 2 "en la segunda cadena de salida no está rompiendo, haciendo que la cadena sea aún más bonita :-)

Cuestiones relacionadas