Question

En C ++, j'ai une variable float / double.

Lorsque j'imprime ceci avec par exemple cout, la chaîne résultante est délimitée par des points.

cout << 3.1415 << endl
$> 3.1415

Existe-t-il un moyen simple de forcer le double à être imprimé avec une virgule?

cout << 3.1415 << endl
$> 3,1415
Était-ce utile?

La solution

imbue() cout avec un locale dont la fonction de membre numpunct de la facette decimal_point() renvoie une virgule.

L'obtention d'un tel std::locale("fr") peut être effectuée de plusieurs manières. Vous pouvez utiliser un paramètre régional nommé disponible sur votre système (do_decimal_point(), peut-être). Vous pouvez également créer votre propre numpuct, y implémenter le <=> membre.

Exemple de la deuxième approche:

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

Utilisé comme:

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

Autres conseils

Vous devez imposer au flux des paramètres régionaux différents, dont la facette num_punct (iirc) spécifie une virgule.

Si les paramètres régionaux de votre plate-forme comportent des virgules,

cout.imbue(locale(""));

devrait suffire.

Ceci est contrôlé par les paramètres régionaux de votre programme.

La manière dont vous définissez les paramètres régionaux par défaut d'un programme dépend de la plate-forme. Sur les plates-formes de type POSIX, il s’agit par exemple des variables d’environnement LANG et LC_ *.

Vous pouvez forcer un environnement local particulier (différent de celui par défaut) dans un programme C ++ en appelant ios :: imbue. Quelque chose comme cela pourrait fonctionner:

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

L'idée est de forcer les paramètres régionaux où la virgule est le séparateur décimal. Vous devrez peut-être ajuster le & Quot; German_germany & Quot; chaîne pour obtenir le comportement que vous voulez sur votre plate-forme particulière.

Pour être précis, ceci est contrôlé par la valeur std::numpunct<charT>::decimal_point(). Vous pouvez imbue() utiliser un autre environnement local avec un autre decimal_point()

.

Ancien fil de discussion, mais de toute façon ... Il faut savoir que l'utilisation d'un std::locale rend la chaîne & "jolie &"; complète avec le point décimal correct, des séparateurs de milliers et ce qui ne l'est pas, selon la plate-forme et la locale. Très probablement, utiliser imbue() interrompt toute analyse de la chaîne après sa mise en forme. Par exemple:

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

donne le résultat suivant:
without locale: 1234.56
with fr locale: 1 234,56

L'utilisation de strtod() ou similaire sur la deuxième chaîne ne fonctionnera probablement pas très bien ... De même, l'espace entre & "; 1 &"; et " 2 " dans la deuxième chaîne de sortie est une chaîne insécable, la rendant encore plus jolie: -)

Très vieux fil, mais enfin ... J'ai eu le problème de remplir une entrée de texte sous Gtkmm-3.0 avec le résultat d'un calcul de distance. Pour clarifier les choses, j’ajoute un exemple dans lequel j’ai concentré quelques idées reçues de plusieurs articles lus au cours des derniers jours:

#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());
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top