2010-06-28 19 views
6

Il mio codice è fondamentalmente questo:C++: caratteri larghi che escono in modo errato?

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

message += japan; 

wprintf(message.c_str()); 

sto che desiderano utilizzare ampi archi, ma non so come stanno emessi, così ho usato wprintf. Quando eseguo qualcosa come:

./widestr | hexdump 

I Codepoints esadecimali creare questo:

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 ? ? 

Perché sono tutti saltati in ordine? Voglio dire, se il wprintf è sbagliato, non capisco perché abbia prodotto un ordine così disordinato!

modifica: endianness o qualcosa del genere? sembrano ruotare ogni due personaggi. eh.

MODIFICA 2: Ho provato a utilizzare wcout, ma restituisce esattamente gli stessi esadecimali codepoint. Strano!

+0

Forse dovresti provare "cout << messaggio << endl'. – phimuemue

+0

@phimuemue, Non funziona, mi invia all'incirca 30 errori, in primo luogo 'widestr.cpp: 18: errore: nessuna corrispondenza per 'operatore <<' in 'std :: cout << messaggio'', compresi molti su tratti di ostream char o qualcosa del genere, non emetterà la stringa larga! –

+1

Che piattaforma e compilatore stai usando? – hlovdal

risposta

11

è necessario definire 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; 
    } 

funziona come previsto (vale a dire convertire un'ampia stringa di restringere UTF-8 e stamparlo).

Quando si definisce locale globale per "" - si imposta locale del sistema (e se è UTF-8 sarebbe essere stampato come UTF-8 - cioè wstring saranno convertiti)

Edit: dimentica quello che ho detto su sync_with_stdio - questo non è corretto, sono sincronizzati per impostazione predefinita. Non necessario.

+1

Suona come "sync_with_stdio' e' wcout' sono alternative; fanno cose completamente diverse. 'sync_with_stdio' è richiesto se si desidera interlacciare le funzioni del flusso C (come' wprintf') con l'utilizzo del flusso C++ ('wcout'); 'imbusta' è necessario se vuoi cambiare le impostazioni locali usate da' wcout'. –

+0

Non riesco a testarlo, ma 'wcout' dovrebbe funzionare senza le impostazioni della codepage su Windows perché' wchar_t' è un'unità di codice UTF-16 su Windows e UTF-16 è l'unica codifica nativa di Windows. Quindi 'std :: wcout' dovrebbe usare' WriteConsoleW' senza alcuna conversione di locale. In caso contrario, si tratta di un errore di libreria. – Philipp

+2

@Philipp Non è come viene definito dallo standard. Lo standard dice che i caratteri ampi dovrebbero essere convertiti in codifica stretta secondo la codepage delle impostazioni locali. E questo è ciò che è fatto. Il problema con Windows è che non supporta UTF-8. Quindi per Windows probabilmente devi usare 'locale :: globale (locale (" Japan "))' e userebbe la codifica Shift-JIS in uscita. Altrimenti non riuscirebbe a convertire i caratteri. – Artyom

Problemi correlati