2013-03-05 14 views
8

Ich möchte pi als 3,141592 anstelle von 3.141592 lesen und schreiben, da die Verwendung des Kommas in vielen europäischen Ländern üblich ist. Wie kann ich dies mit iostream s erreichen? Mit anderen WortenWie kann ich das Dezimaltrennzeichen auf ein Komma setzen?

cout << 3.141592; 

sollte

3,141592 

auf die Standardausgabe drucken.

+0

Sie meinen, in Code? Wie 'doppeltes x = 3,14;'? –

+0

Nein in Standardausgabe, Eingabe, Lesen und Schreiben von Dateien zur Laufzeit (nicht zur Kompilierzeit). –

+6

ein Wort: Gebietsschemas. – PlasmaHH

Antwort

14

Sie sollten basic_ios::imbue verwenden, um das bevorzugte Gebietsschema festzulegen.

Werfen Sie einen Blick hier: http://www.cplusplus.com/reference/ios/ios_base/imbue/

Locales können Sie die bevorzugte Art und Weise durch den Benutzer verwenden, so dass, wenn ein Computer in Italien Komma getrennte Dezimalstellen verwendet, wird der Punkt in den USA nach wie vor verwendet. Die Verwendung von Ländereinstellungen ist eine gute Vorgehensweise.

Aber wenn Sie ausdrücklich wollen, um die Verwendung des Kommas erzwingen, werfen Sie einen Blick hier: http://www.cplusplus.com/reference/locale/numpunct/decimal_point/

Hier ein kleines Beispiel, das ich nur mit g ++ gemacht, das das Zeichen erzwingt ‚‘ (vorbei an den Separator als Vorlage Argument ist nur zum Spaß, nicht wirklich notwendig)

#include <iostream> 
#include <locale> 

template <class charT, charT sep> 
class punct_facet: public std::numpunct<charT> { 
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<char, ','>)); 
    std::cout << "My age is " << 3.1415 << " lightyears.\n"; 
} 

Beachten Sie, dass cout.getloc() mit Mir zwingende nur eine einzige Facette in dem aktuell eingestellten Gebietsschema, das heißt, in den aktuellen locale-Einstellungen von cout, ich bin zu ändern nur wie die Interpunktion ausgeführt wird.

do_decimal_point ist eine virtuelle Funktion von std::numpunct, die Sie neu definieren können, um Ihren benutzerdefinierten Separator bereitzustellen. Diese virtuelle Funktion wird von numpunct::decimal_point beim Drucken Ihrer Nummer verwendet.

9

Wie @AkiRoss sagte, müssen Sie Gebietsschemas verwenden. Im Allgemeinen in jedem Programm, das Sie das globale Locale an die Benutzer Wahl, indem so etwas wie eingestellt sein schreiben, eine der ersten Aktionen in main sollte:

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

Dies sollte systematisch , in jede Programm, das mit einem menschlichen Benutzer interagiert. Alle danach geöffneten Dateien werden automatisch mit dem korrekten Gebietsschema versehen.

Alternativ können Sie explizit das Gebietsschema angeben, die Sie verwenden möchten:

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

Das Problem dabei ist, dass es keinen Standard für locale Namen. So etwas wie "it_IT.UTF-8" entspricht dem Posix Standard und wird im Internet verwendet; Windows hat traditionell ein anderes Format verwendet (obwohl die letzten Windows scheinen dieses Format auch akzeptieren).

Welche Blätter std::cin, std::cout und std::cerr.Diese sind geöffnet, bevor Sie main eingeben, und muss daher mit dem neuen Gebietsschema durchdrungen sein. (Wenn Sie eine Kopie des aktuellen globalen locale zu erhalten, verwenden der Standardkonstruktor von std::locale.)

Schließlich, wenn Sie alle Binärdateien sind Öffnen, bewusst sein, dass sie wird auch mit dem globalen locale durchdrungen werden. Was kann Code Übersetzung tun. In solchen Fällen sollten Sie sie explizit mit std::locale::classic() einbetten oder ein neues Gebietsschema erstellen, indem Sie die Facette des codecvt von std::locale::classic() mit den anderen Facetten des globalen Gebietsschemas zusammenführen. (std::locale hat spezielle Funktionen und Konstruktoren dafür.)