2010-06-28 4 views
6

Mein Code ist im Grunde diese:C++: breite Zeichenausgabe falsch?

wstring japan = L"日本"; 
wstring message = L"Welcome! Japan is "; 

message += japan; 

wprintf(message.c_str()); 

Ich wünsche Wide-Strings zu verwenden, aber ich weiß nicht, wie sie ausgegeben sind, so habe ich wprintf. Wenn ich etwas laufen wie:

./widestr | hexdump 

Die hexadezimale Codepoints erstellen Diesen:

65 57 63 6c 6d 6f 21 65 4a 20 70 61 6e 61 69 20 20 73 3f 3f 
e W c l m o ! e J  p a n a i  s ? ? 

Warum sind sie alle, um gesprungen? Ich meine, wenn der wprintf falsch ist, verstehe ich immer noch nicht, warum er in so einer bestimmten Reihenfolge ausgegeben wurde!

edit: endianess oder sowas? Sie scheinen jeweils zwei Charaktere zu drehen. huh.

EDIT 2: Ich habe versucht, wcout, aber es gibt die exakt gleichen hexadezimalen Codepoints. Seltsam!

+0

Vielleicht sollten Sie 'cout << Nachricht << endl versuchen. – phimuemue

+0

@phimuemue, Es funktioniert nicht, es sendet mir etwa 30 Fehler, erstens 'widestr.cpp: 18: Fehler: keine Übereinstimmung für 'Operator <<' in 'std :: cout << Nachricht', einschließlich viele über ostream char Merkmale oder etwas, Es wird nicht die breite Zeichenfolge ausgeben! –

+1

Welche Plattform und welchen Compiler benutzen Sie? – hlovdal

Antwort

11

Sie benötigen locale

#include <stdio.h> 
    #include <string> 
    #include <locale> 
    #include <iostream> 

    using namespace std; 

    int main() 
    { 

      std::locale::global(std::locale("")); 
      wstring japan = L"日本"; 
      wstring message = L"Welcome! Japan is "; 

      message += japan; 

      wprintf(message.c_str()); 
      wcout << message << endl; 
    } 

funktioniert wie erwartet (das heißt konvertieren breite Zeichenfolge zu verengen UTF-8 und ausdrucken) zu definieren.

Wenn Sie globale Locale auf "" definieren - Sie Systemgebietsschema festgelegt (und wenn es UTF-8 ist, wäre es als UTF-8 ausgedruckt werden - dh wstring wird umgewandelt werden)

Edit: vergiss, was ich über sync_with_stdio gesagt habe - das ist nicht korrekt, sie sind standardmäßig synchronisiert. Nicht benötigt.

+1

Sie lassen es klingen wie 'sync_with_stdio' und' wcout' sind Alternativen; sie machen ganz andere Dinge. 'sync_with_stdio' ist erforderlich, wenn C-Stream-Funktionen (wie' wprintf') mit der C++ - Stream-Verwendung ('wcout') verschachtelt werden sollen; 'imbue' wird benötigt, wenn Sie das von' wcout' verwendete Gebietsschema ändern wollen. –

+0

Ich kann es nicht testen, aber 'wcout' sollte ohne Codepage-Einstellungen unter Windows funktionieren, da' wchar_t' eine UTF-16-Codeeinheit unter Windows ist und UTF-16 die einzige native Codierung von Windows ist. Daher sollte 'std :: wcout' 'WriteConsoleW' ohne Gebietsschemaumwandlung verwenden. Wenn nicht, ist es ein Bibliotheksfehler. – Philipp

+2

@Philipp Es ist nicht wie dies durch den Standard definiert ist. Standard besagt, dass breite Zeichen entsprechend der Codepage des Gebietsschemas in schmale Codierung konvertiert werden sollten. Und das ist, was getan wird. Das Problem mit Windows ist, dass UTF-8 nicht unterstützt wird. Also für Windows müssen Sie wahrscheinlich 'locale :: globale (locale (" Japan "))' und es würde Shift-JIS-Codierung in der Ausgabe verwenden. Andernfalls würde es nicht möglich sein, Zeichen zu konvertieren. – Artyom