2012-11-15 13 views
6

Ich habe ein Problem beim Schreiben französischer Zeichen auf die Konsole in C++. Die Zeichenfolge wird aus einer Datei mithilfe von std::ifstream und std::getline geladen und dann unter Verwendung von std::cout auf die Konsole gedruckt. Hier ist, was die Zeichenfolge in der Datei ist:Wie kann man lateinische Zeichen in der C++ - Konsole unter Windows richtig drucken?

La Chaîne qui entsprechen au-Code "TEST_CODE" n'a pas été trouvée à l'aide locale "fr".

Und hier ist, wie die Zeichenfolge gedruckt wird:

La Chane qui entsprechen au-Code "TEST_CODE" n'a pas UTU trouvÚe Ó l'aide locale "fr".

Wie kann ich dieses Problem beheben?

+0

Ich nehme an, Sie verwenden Windows? –

+0

Ja ich bin, werde meine Frage ändern, um anzugeben. – jmegaffin

+0

@Boreal: Stellen Sie sicher, dass Sie die in der Datei gespeicherte Zeichenfolge in Unicode UTF-16 konvertieren (was als Unicode-Codierung in einer Windows-Anwendung sinnvoll ist). Sie können das tun, indem Sie die Zeichenfolge aus Ihrer Datei lesen und dann 'MultiByteToWideChar()' API (oder ATL-Umwandlungshilfe 'CA2W') verwenden, um von Ihrer spezifischen Codierung in UTF-16 zu konvertieren. Um dann eine Unicode-Zeichenfolge in die Konsole zu drucken, müssen Sie die Konsole nur mit _setmode (_fileno (stdout), _O_U16TEXT); 'initialisieren, und dann können Sie' wprintf() 'oder' std :: wcout' verwenden. Siehe meine Antwort für weitere Details und Links. –

Antwort

5

Das Problem besteht darin, dass die Konsole andere Codepages als der Rest des Systems verwendet. Zum Beispiel verwenden normalerweise Windows-Systeme, die für Amerika und Westeuropa eingerichtet wurden, CP1252, aber die Konsole in diesen Regionen verwendet CP437 oder CP850.

Sie können entweder die Ausgabe-Codepage der Konsole an die von Ihnen verwendete Codierung anpassen oder Sie können die Zeichenfolgen so konvertieren, dass sie der Ausgabe-Codepage der Konsole entsprechen.

Stellen Sie die Konsolenausgabe Codepage:

SetConsoleOutputCP(GetACP()); // GetACP() returns the system codepage. 
std::cout << "La chaîne qui correspond au code \"TEST_CODE\" n'a pas été trouvée à l'aide locale \"fr\"."; 

Oder ein von vielen Möglichkeiten zwischen Codierungen (dies erfordert VS2010 oder höher) zu konvertieren:

#include <codecvt> // for wstring_convert 
#include <locale> // for codecvt_byname 
#include <iostream> 

int main() { 
    typedef std::codecvt_byname<wchar_t,char,std::mbstate_t> codecvt; 

    // the following relies on non-standard behavior, codecvt destructors are supposed to be protected and unusable here, but VC++ doesn't complain. 
    std::wstring_convert<codecvt> cp1252(new codecvt(".1252")); 
    std::wstring_convert<codecvt> cp850(new codecvt(".850")); 

    std::cout << cp850.to_bytes(cp1252.from_bytes("...été trouvée à...\n")).c_str(); 
} 

Letzteres Beispiel vorausgesetzt, dass Sie in der Tat müssen Sie zwischen 1252 und 850 konvertieren. Sie sollten wahrscheinlich die Funktion GetOEMCP() verwenden, um die tatsächliche Zielcodepage herauszufinden, und die Quellcodepage hängt tatsächlich davon ab, was Sie für den Quellcode und nicht für das Ergebnis von GetACP() verwenden die Maschine, auf der das Programm läuft.

Beachten Sie auch, dass dieses Programm auf etwas angewiesen ist, das nicht vom Standard garantiert wird: dass die wchar_t-Codierung zwischen Gebietsschemata aufgeteilt wird. Dies gilt für die meisten Plattformen — normalerweise einige Unicode-Codierung wird für wchar_t in allen Gebietsschemas verwendet —, aber nicht alle.


Idealerweise könnte man nur UTF-8 verwenden, überall und die folgenden gut funktionieren würde, wie es auf anderen Plattformen in diesen Tagen tut:

#include <iostream> 

int main() { 
    std::cout << "La chaîne qui correspond au code \"TEST_CODE\" n'a pas été trouvée à l'aide locale \"fr\".\n"; 
} 

Leider kann von Windows nicht unterstützt UTF-8 auf diese Weise ohne entweder UTF-16 als die wchar_t-Kodierung aufzugeben und ein 4-Byte-wchar_t zu übernehmen oder die Anforderungen des Standards zu verletzen und standardkonforme Programme zu brechen.

+0

Wenn Sie sagen, setzen Sie die Ausgabe-Codepage der Konsole, wie würde ich das machen? – jmegaffin

+0

@Boreal, verwenden Sie den Befehl 'chcp', um die aktuelle Codepage anzuzeigen oder um sie auf etwas anderes zu setzen. –

+0

Ich stimme dieser Antwort im Prinzip zu, aber die Codeseiten scheinen nicht übereinzustimmen. Ich kann keine Kombination finden, die mit der Eingabe und Ausgabe des Samples übereinstimmt. –

1

Wenn Sie Unicode-Zeichen in der Konsole zu schreiben, müssen Sie einige Initialisierung tun:

_setmode(_fileno(stdout), _O_U16TEXT); 

dann Ihre Französisch Zeichen korrekt angezeigt werden (ich habe es Consolas als meine Konsole-Schriftart getestet):

#include <fcntl.h> 
#include <io.h> 

#include <iostream> 
#include <ostream> 
#include <string> 

using namespace std; 

int main() 
{ 
    // Prepare console output in Unicode 
    _setmode(_fileno(stdout), _O_U16TEXT); 


    // 
    // Build Unicode UTF-16 string with French characters 
    // 

    // 0x00EE - LATIN SMALL LETTER I WITH CIRCUMFLEX 
    // 0x00E9 - LATIN SMALL LETTER E WITH ACUTE 
    // 0x00E0 - LATIN SMALL LETTER A WITH GRAVE 

    wstring str(L"La cha"); 
    str += L'\x00EE'; 
    str += L"ne qui correspond au code \"TEST_CODE\" "; 
    str += L"n'a pas "; 
    str += L'\x00E9'; 
    str += L't'; 
    str += L'\x00E9'; 
    str += L" trouv"; 
    str += L'\x00E9'; 
    str += L"e "; 
    str += L'\x00E0'; 
    str += L" l'aide locale \"fr\"."; 


    // Print the string to the console 
    wcout << str << endl; 
} 

Betrachten Sie die folgenden Blog-Beiträge von Michael Kaplan zu lesen:

Außerdem, wenn Sie einen Text aus einer Datei lesen, müssen Sie wissen, welche Codierung verwendet wird: UTF-8? UTF-16LE? UTF-16BE? Eine bestimmte Codepage? Dann können Sie von der spezifischen Codierung in Unicode UTF-16 konvertieren und UTF-16 in einer Windows-Anwendung verwenden. Um von einer Codepage (oder von UTF-8) in UTF-16 zu konvertieren, können Sie MultiByteToWideChar() API oder ATL conversion helper class CA2W verwenden.

Verwandte Themen