Come stampare un doppio con una virgola
-
07-07-2019 - |
Domanda
In C ++ ho una variabile float / double.
Quando lo stampo con cout ad esempio, la stringa risultante è delimitata da punti.
cout << 3.1415 << endl
$> 3.1415
C'è un modo semplice per forzare la stampa del doppio con una virgola?
cout << 3.1415 << endl
$> 3,1415
Soluzione
imbue() cout
con un locale
la cui numpunct
funzione membro decimal_point()
di facet restituisce una virgola.
È possibile ottenere tale std::locale("fr")
in diversi modi. È possibile utilizzare un'impostazione internazionale denominata disponibile sul sistema (do_decimal_point()
, forse). In alternativa, potresti derivare il tuo numpuct, implementare il <=> membro in esso.
Esempio del secondo approccio:
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;
};
Utilizzato come:
std::cout.imbue(std::locale(std::cout.getloc(), new DecimalSeparator<char>(',')));
Altri suggerimenti
Devi imputare lo stream con una locale diversa, una la cui sfaccettatura num_punct (iirc) specifica una virgola.
Se le impostazioni internazionali della piattaforma vengono formattate con virgole, quindi
cout.imbue(locale(""));
dovrebbe essere sufficiente.
Questo è controllato dalla locale del tuo programma.
La modalità di impostazione delle impostazioni internazionali predefinite di un programma dipende dalla piattaforma. Su piattaforme di tipo POSIX, è ad esempio con le variabili di ambiente LANG e LC_ *.
È possibile forzare una determinata locale - diversa da quella predefinita - all'interno di un programma C ++ chiamando ios :: imbue. Qualcosa del genere potrebbe funzionare:
#include <locale>
cout.imbue(std::locale("German_germany"));
L'idea è di forzare una locale in cui virgola è il separatore decimale. Potrebbe essere necessario regolare & Quot; German_germany & Quot; stringa per ottenere il comportamento desiderato sulla tua piattaforma specifica.
Per essere precisi, questo è controllato dal valore std::numpunct<charT>::decimal_point()
. Puoi imbue()
un'altra locale con un'altra decimal_point()
Vecchio thread, ma comunque ... Bisogna essere consapevoli del fatto che l'uso di std::locale
rende la stringa " pretty " ;, completa con il corretto punto decimale, migliaia di separatori e cosa no, a seconda di la piattaforma e le impostazioni locali. Molto probabilmente, l'uso di imbue()
interromperà qualsiasi analisi della stringa dopo che è stata formattata. Ad esempio:
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();
Fornisce il seguente output:
without locale: 1234.56
with fr locale: 1 234,56
L'uso di strtod()
o simile sulla seconda stringa probabilmente non funzionerà molto bene ... Inoltre, lo spazio tra " 1 " e " 2 " nella seconda stringa di output è una stringa non interrotta, che rende la stringa ancora più bella :-)
Discussione molto vecchia, ma comunque ... ho avuto il problema di riempire una voce di testo in Gtkmm-3.0 con il risultato di un calcolo della distanza. Per chiarire le cose, aggiungo un esempio, in cui ho concentrato alcune saggezza di diversi post che ho letto negli ultimi giorni:
#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());