Comment définir le séparateur décimal sur une virgule?

J’aimerais lire et écrire pi en tant que 3,141592 au lieu de 3.141592 , car l’utilisation de la virgule est courante dans de nombreux pays européens. Comment puis-je accomplir cela avec iostream s? En d’autres termes

 cout << 3.141592; 

devrait imprimer

 3,141592 

à la sortie standard.

Vous devez utiliser basic_ios::imbue pour définir les parameters régionaux préférés.

Jetez un oeil ici: http://www.cplusplus.com/reference/ios/ios_base/imbue/

Les parameters régionaux vous permettent d’utiliser la méthode préférée de l’utilisateur. Par conséquent, si un ordinateur en Italie utilise des virgules pour séparer les chiffres décimaux, le point est toujours utilisé aux États-Unis. Utiliser des locales est une bonne pratique.

Mais si vous souhaitez forcer explicitement l’utilisation de la virgule, consultez la page suivante : http://www.cplusplus.com/reference/locale/numpunct/decimal_point/

Voici un petit exemple que je viens de faire avec g ++ qui applique le caractère ‘,’ (passer le séparateur en tant qu’argument de modèle est juste pour le plaisir, pas vraiment nécessaire)

 #include  #include  template  class punct_facet: public std::numpunct { protected: charT do_decimal_point() const { return sep; } }; int main(int argc, char **argv) { std::cout.imbue(std::locale(std::cout.getloc(), new punct_facet)); std::cout << "My age is " << 3.1415 << " lightyears.\n"; } 

Notez qu'en utilisant cout.getloc() je ne redéfinis qu'une seule facette dans les parameters régionaux actuellement définis, c'est-à-dire que, dans les parameters régionaux actuels de cout, je ne modifie que la façon dont la ponctuation est effectuée.

do_decimal_point est une fonction virtuelle de std::numpunct que vous pouvez redéfinir pour fournir votre séparateur personnalisé. numpunct::decimal_point utilisera cette fonction virtuelle lors de l’impression de votre numéro.

Comme @AkiRoss l’a dit, vous devez utiliser des parameters régionaux. En général , dans tout programme que vous écrivez, l’une des toutes premières actions de main devrait être de définir les parameters régionaux globaux sur le choix de l’utilisateur, en procédant comme suit:

 std::locale::global( std::locale( "" ) ); 

Cela devrait être systématique, dans chaque programme qui interagit avec un utilisateur humain. Tous les fichiers ouverts après cela seront automatiquement imprégnés des parameters régionaux appropriés.

Vous pouvez également spécifier explicitement les parameters régionaux que vous souhaitez utiliser:

 std::locale::global( std::locale( locale_name ) ); 

Le problème, c’est qu’il n’y a pas de norme pour les noms de parameters régionaux. Quelque chose comme "it_IT.UTF-8" correspond au standard Posix et est utilisé sur Internet; Windows utilise traditionnellement un format différent (bien que Windows récent semble également accepter ce format).

Ce qui laisse std::cin , std::cout et std::cerr . Celles-ci sont ouvertes avant d’entrer dans main et doivent donc être imprégnées des nouveaux parameters régionaux. (Pour obtenir une copie des parameters régionaux globaux actuels, utilisez le constructeur par défaut de std::locale .)

Enfin, si vous ouvrez des fichiers binarys, sachez qu’ils seront également imprégnés des parameters régionaux. Qui peut faire la traduction de code. Dans de tels cas, vous devez les imprégner explicitement de std::locale::classic() ou créer un nouvel environnement local en fusionnant la facette codecvt de std::locale::classic() avec les autres facettes de l’environnement local global. ( std::locale a des fonctions spéciales et des constructeurs pour cela.)