2010-04-29 9 views
12

Non riesco a iniziare con la libreria ICU C++. Ho cercato di ottenere l'esempio più semplice per funzionare, ma anche quello ha fallito. Vorrei solo produrre una stringa UTF-8 e poi andare da lì.Uscita C++ UTF-8 con ICU

Ecco quello che ho:

#include <unicode/unistr.h> 
#include <unicode/ustream.h> 

#include <iostream> 

int main() 
{ 
    UnicodeString s = UNICODE_STRING_SIMPLE("привет"); 

    std::cout << s << std::endl; 

    return 0; 
} 

Ecco l'output:

$ g++ -I/sw/include -licucore -Wall -Werror -o icu_test main.cpp 
$ ./icu_test 
пÑÐ¸Ð²ÐµÑ 

mio supporto del terminale e il carattere UTF-8 e io uso regolarmente il terminale con UTF-8. Il mio codice sorgente è in UTF-8.

Penso che forse ho in qualche modo bisogno di impostare il flusso di output su UTF-8 perché ICU memorizza stringhe come UTF-16, ma non sono sicuro e avrei pensato che gli operatori forniti da ustream.h avrebbero fallo comunque.

Qualsiasi aiuto sarebbe apprezzato, grazie.

+1

hai provato a usare std :: wcout? – Milan

+1

Sì, ma ICU non sembra fornire un operatore << per questo, quindi ho solo una lunga lista di errori da g ++. – Isaac

+0

Hai archiviato un bug su wcout? (per favore? :) (con giustificazione?) –

risposta

12

Il programma funziona solo se si cambia l'inizializzazione a:

UnicodeString s("привет"); 

La macro si sta utilizzando è only for strings that contain "invariant characters", i.e., only latin letters, digits, and some punctuation.

Come è stato detto prima, le codepage di input/output sono complicate. Hai detto:

mio terminale e il supporto dei font UTF-8 e Io uso regolarmente il terminale con UTF-8. Il mio codice sorgente è in UTF-8.

Questo può essere vero, ma ICU non sa che è vero. La codepage di processo potrebbe essere diversa (diciamo iso-8859-1) e la codepage di output potrebbe essere diversa (diciamo shift-jis). Quindi, il programma non funzionerebbe. Ma i caratteri invarianti che utilizzano l'API UNICODE_STRING_SIMPLE funzionerebbero comunque.

Spero che questo aiuti.

srl, dev ICU

+0

Grazie! Questo funziona davvero. Dal momento che hai firmato con 'icu dev', forse lo saprai: conosci qualche canale IRC per l'aiuto dell'ICU? Ho cercato, ma non ho trovato nessuno. – Isaac

+0

Non conosco alcun canale IRC: siamo così popolari? A volte guardo qui (e occasionalmente faccio altre ricerche sul web) ma la nostra mailing list e database di bug su http://icu-project.org sono i canali principali. Questa è un'idea interessante. Potresti proporlo lì. Sono il responsabile tecnico per ICU per C/C++. –

+0

Beh, ho fatto un sacco di ricerche negli ultimi giorni, alla ricerca di una soluzione Unicode e ICU è considerata la "migliore" per C++ da tutte le fonti che ho letto. Tutte le stesse fonti si lamentano anche del fatto che la documentazione è gravemente carente e ci sono molti altri post sul forum che dicono la stessa cosa. Dato che non riuscivo nemmeno a far funzionare un programma di stile "ciao mondo", sarei d'accordo, scusa. So che non è colpa tua, ma se hai qualche influenza, ti preghiamo di formulare alcuni suggerimenti sul miglioramento dei documenti. – Isaac

2

Che cosa succede se si scrive l'output in un file (sia reindirizzamento utilizzando tubi dal terminale, oppure aprendo un flusso di file nel programma stesso)

che avrebbe determinato se sia o non è il terminale che non riesce per gestire l'output correttamente.

Cosa succede se si controlla la stringa di output nel debugger? Contiene i valori corretti? Scopri come la codifica UTF-8 della tua stringa dovrebbe apparire come e confrontarla con ciò che ottieni nel debugger. Oppure stampare il valore integrale di ciascun byte e verificare che siano corretti.

Quando si lavora con la codifica, è sempre difficile (ma essenziale) determinare se il problema si trova nel programma stesso o nella conversione che si verifica quando il testo viene inviato al sistema. Estrarre il terminale dall'equazione e verificare che il programma generi l'output corretto.

+0

Scrivere in un file è un ottimo passo per il debug delle codifiche. –

+0

Ho appena scritto sul file e ottengo lo stesso risultato. Daremo un'occhiata al debugger proprio ora. – Isaac

1

operator<<(ostream, UnicodeString) converte tra UTF16 e caratteri utilizzando "convertitore di default" di terapia intensiva.AFAIU, il "convertitore predefinito" (se non lo si imposta esplicitamente con ucnv_setDefaultName()) dipende dalla piattaforma e dal modo in cui è stata compilata l'ICU. Cosa ottieni da ucnv_getDefaultName()?

+1

FWIW lo strumento autonomo 'icuinfo' riporta la codepage predefinita di 4.4. Il convertitore predefinito può provenire da molti luoghi selvaggi e meravigliosi. –

+0

Il mio problema è stato risolto, ma per rispondere alla tua domanda ottengo "en_GB". – Isaac

+1

icuinfo deve restituire qualcosa del tipo: Locale predefinito: en_US ... Convertitore predefinito: UTF-8 –