Como imprimir um casal com uma vírgula
-
07-07-2019 - |
Pergunta
Em C ++ Eu tenho um duplo variável / float.
Quando eu imprimir esta com por exemplo cout a cadeia resultante é delimitada por ponto.
cout << 3.1415 << endl
$> 3.1415
Existe uma maneira fácil para forçar o casal a ser impresso com uma vírgula?
cout << 3.1415 << endl
$> 3,1415
Solução
imbue() cout
com um locale
cuja numpunct
da faceta função de membro decimal_point()
retornos uma vírgula.
A obtenção de tal locale
pode ser feito de várias maneiras. Você poderia usar uma localidade chamada disponível em seu sistema (std::locale("fr")
, talvez). Alternativamente, você pode derivar sua própria numpuct, implementar o membro do_decimal_point()
nele.
Exemplo da segunda abordagem:
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;
};
Usado como:
std::cout.imbue(std::locale(std::cout.getloc(), new DecimalSeparator<char>(',')));
Outras dicas
Você precisa impue o fluxo com uma localidade diferente, aquele cuja num_punct (IIRC) faceta especifica uma vírgula.
Se os seus formatos localidade plataforma com vírgulas, então
cout.imbue(locale(""));
deve ser suficiente.
Este é controlada pelo local do seu programa.
Como você definir localidade padrão do programa depende da plataforma. Em plataformas tipo POSIX, é com as * variáveis ??de ambiente LANG e LC_, por exemplo.
Você pode forçar uma localidade específica - diferente do padrão - dentro de um programa C ++ chamando ios :: Imbue. Algo como este trabalho poder:
#include <locale>
cout.imbue(std::locale("German_germany"));
A idéia é forçar um local onde vírgula é o separador decimal. Talvez seja necessário ajustar a string "German_germany" para obter o comportamento desejado em sua plataforma particular.
Para ser preciso, isso é controlado pelo valor std::numpunct<charT>::decimal_point()
. Você pode imbue()
outro local com outro decimal_point()
discussão antiga, mas de qualquer maneira ... Um deve estar ciente de que usando um std::locale
faz a string "bonito", completa com ponto decimal correto, milhares separadores eo que não, dependendo da plataforma e localidade. Muito provavelmente, usando imbue()
vai quebrar qualquer análise da cadeia depois ele é formatado. Por exemplo:
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();
Dá o seguinte resultado:
without locale: 1234.56
with fr locale: 1 234,56
Usando strtod()
ou similar na segunda corda, provavelmente, não vai funcionar muito bem ... Além disso, o espaço entre "1" e "2" na segunda cadeia de saída é um não-quebrando um, fazendo a corda ainda mais bonita : -)
fio muito velho, mas de qualquer maneira ... Eu tive o problema de preencher uma entrada de texto sob Gtkmm-3.0 com o resultado de um cálculo de distância. Para tornar as coisas mais claras eu adicionar um exemplo, onde eu me concentrei alguns sabedorias de vários posts que li nos últimos dias:
#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());