2015-07-22 18 views
5

Ich versuche, das chinesische Schriftzeichen mit den Typen wchar_t, char16_t und char32_t, ohne Erfolg (live example)Ich versuche, ein chinesisches Zeichen mit den Typen wchar_t, char16_t und char32_t, ohne Erfolg zu drucken.

#include <iostream> 
int main() 
{ 
    char x[] = "中";   // Chinese character with unicode point U+4E2D 
    char y[] = u8"中"; 
    wchar_t z = L'中'; 
    char16_t b = u'\u4e2d'; 
    char32_t a = U'\U00004e2d'; 

    std::cout << x << '\n';  // Ok 
    std::cout << y << '\n';  // Ok 
    std::wcout << z << '\n'; // ?? 
    std::cout << a << '\n';  // prints the decimal number (20013) corresponding to the unicode point U+4E2D 
    std::cout << b << '\n';  //    "     "     " 
} 
+0

std :: wcout nicht funktioniert, wenn Sie versuchen, Text zu schreiben, die nicht in Ihrem Standard-Gebietsschema dargestellt werden können. – WorldSEnder

+1

C++ hat keine verwendbare Unicode-Unterstützung. Wenn Sie eine (nicht triviale) Unicode-Behandlung benötigen, verwenden Sie eine dedizierte Bibliothek wie [ICU] (http://site.icu-project.org/). (Ja, Sie können etwas mit 'std :: string' auf Nicht-Windows und' wstring' auf Windows machen, aber meh). –

+0

@BaummitAugen Es scheint mit UTF-8 zu arbeiten –

Antwort

5

Da Sie laufen Ihren Test auf einem Linux-System, Quellcode zu drucken UTF- 8, weshalb x und y sind das gleiche. Diese Bytes werden unmodifiziert in die Standardausgabe von std::cout << x und std::cout << y weitergeleitet, und wenn Sie die Webseite anzeigen (oder wenn Sie das Linux-Terminal betrachten), sehen Sie das Zeichen wie erwartet.

std::wcout << z drucken, wenn Sie zwei Dinge tun:

std::ios::sync_with_stdio(false); 
std::wcout.imbue(std::locale("en_US.utf8")); 

ohne unsynching von C, GNU libstdC++ geht durch C IO-Streams, die nie ein breites Zeichen nach dem Drucken einen schmalen char auf dem gleichen Strom drucken. LLVM libC++ scheint sogar synchron zu funktionieren, benötigt aber natürlich immer noch den Befehl, dem Stream mitzuteilen, wie die breiten Zeichen in die Bytes konvertiert werden, die er in die Standardausgabe sendet.

Um b und a zu drucken, müssen Sie sie in breit oder schmal konvertieren; sogar mit wbuffer_convert Einrichten eines Char32_t-Stream ist eine Menge Arbeit. Es würde wie folgt aussehen:

std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> conv32; 
std::cout << conv32.to_bytes(a) << '\n'; 

Dass sie alle zusammen: http://coliru.stacked-crooked.com/a/a809c38e21cc1743