2015-07-22 15 views
5

Próbuję wydrukować chiński znak wykorzystaniem rodzajów wchar_t, char16_t i char32_t, bez powodzenia (live example)Próbuję wydrukować chińską literę przy użyciu typów wchar_t, char16_t i char32_t, bezskutecznie.

#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 nie działa, jeśli starają się pisać teksty, które nie mogą być reprezentowane w domyślnej lokalizacji. – WorldSEnder

+1

C++ nie ma obsługiwanej obsługi standardu Unicode. Jeśli potrzebujesz (nie trywialnej) obsługi Unicode, użyj dedykowanej biblioteki takiej jak [ICU] (http://site.icu-project.org/). (Tak, możesz zrobić coś z 'std :: string' na systemach innych niż Windows i' wstring' na Windowsie, ale meh). –

+0

@BaummitAugen Wydaje się pracować z UTF-8 –

Odpowiedz

5

Ponieważ używasz test na systemie Linux, kod źródłowy jest UTF- 8, dlatego x i y to to samo. Bajty te są blokowane, niezmodyfikowane, do standardowego wyjścia przez std::cout << x i std::cout << y, a kiedy przeglądasz stronę internetową (lub gdy patrzysz na terminal linuxowy), widzisz postać zgodnie z oczekiwaniami.

std::wcout << z będzie drukować, jeśli nie dwie rzeczy:

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

bez unsynching z C, GNU libstdC++ przechodzi C IO strumieni, które nigdy nie może drukować szeroką char po drukowaniu wąską char na tym samym strumieniu. Wydaje się, że LLVM libC++ działa nawet zsynchronizowane, ale oczywiście nadal potrzebuje imbue, aby powiedzieć strumieniowi, jak konwertować szerokie znaki na bajty wysyłane do standardowego wyjścia. Aby uzyskać wydruk b i a, musisz przekonwertować je na szeroki lub wąski; nawet przy wbuffer_convert skonfigurowanie strumienia char32_t to dużo pracy. to będzie wyglądać następująco:

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

Kładzenie to wszystko razem: http://coliru.stacked-crooked.com/a/a809c38e21cc1743

Powiązane problemy