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
È stato utile?

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());
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top