2014-10-19 18 views
5

Il mio obiettivo è quello di iterare stringhe di Unicode il testo un carattere, ma il codice di seguito viene iterazione unità di codice invece di punti di codice anche se sto usando next32PostInc() che dovrebbe scorrere il codice punti:ICU iterate Codepoints

void iterate_codepoints(UCharCharacterIterator &it, std::string &str) { 
    UChar32 c; 
    while (it.hasNext()) { 
     c = it.next32PostInc(); 
     str += c; 
    } 
} 

void my_test() { 
    const char testChars[] = "\xE6\x96\xAF"; // Chinese character 斯 in UTF-8 
    UnicodeString testString(testChars, ""); 
    const UChar *testText = testString.getTerminatedBuffer(); 

    UCharCharacterIterator iter(testText, u_strlen(testText)); 

    std::string str; 
    iterate_codepoints(iter, str); 
    std::cout << str; // outputs 斯 in UTF-8 format 
} 


int main() { 
    my_test(); 
    return 0; 
} 

il codice precedente produce l'output corretto che è il carattere cinese 斯 ma 3 iterazioni si stanno verificando per questo singolo carattere invece di 1. qualcuno può spiegare quello che sto facendo di sbagliato?

In breve, Voglio solo attraversare i caratteri in un ciclo e sarà felice di utilizzare qualsiasi classe di iterazione ICU necessaria.

Ancora cercando di risolvere questo ...

Ho anche osservato un comportamento cattivo usando UnicodeString come si vede qui sotto. Sto usando VC++ 2013.

void test_02() { 
    // UnicodeString us = "abc 123 ñ";  // results in good UTF-8: 61 62 63 20 31 32 33 20 c3 b1 
    // UnicodeString us = "斯";    // results in bad UTF-8: 3f 
    // UnicodeString us = "abc 123 ñ 斯"; // results in bad UTF-8: 61 62 63 20 31 32 33 20 c3 b1 20 3f (only the last part '3f' is corrupt) 
    // UnicodeString us = "\xE6\x96\xAF"; // results in bad UTF-8: 00 55 24 04 c4 00 24 
    // UnicodeString us = "\x61";   // results in good UTF-8: 61 
    // UnicodeString us = "\x61\x62\x63"; // results in good UTF-8: 61 62 63 
    // UnicodeString us = "\xC3\xB1";  // results in bad UTF-8: c3 83 c2 b1 
    UnicodeString us = "ñ";     // results in good UTF-8: c3 b1  
    std::string cs; 
    us.toUTF8String(cs); 
    std::cout << cs; // output result to file, i.e.: main >output.txt 

}

Sto usando VC++ 2013.

+0

passaggio di un 'char *' da solo al costruttore 'UnicodeString' è soggetto a default della piattaforma tabella codici. '" ñ "' è soggetto al set di caratteri del codice sorgente, ma '" 斯 "' non può essere rappresentato in 8 bit. Il tuo codice sorgente è UTF-8? Questo potrebbe spiegare le tue cattive conversioni. Dovresti utilizzare un costruttore 'UnicodeString' che ti consente di specificare che i dati di origine sono UTF-8 in modo che vengano convertiti correttamente. –

+0

Sì, la mia fonte è in formato UTF-8. –

risposta

6

Dal momento che i dati di origine è UTF-8, è necessario dire che a UnicodeString. Il suo costruttore ha un parametro codepage a tal fine, ma si sta impostando una stringa vuota:

UnicodeString testString(testChars, ""); 

che racconta UnicodeString per eseguire un invariante conversione , che non è quello che si desidera. Si finisce con 3 codepoint (U + 00E6 U + 0096 U + 00AF) invece di 1 codepoint (U + 65AF), motivo per cui il loop itera tre volte.

è necessario modificare la chiamata del costruttore per far UnicodeString conoscere i dati è UTF-8, ad esempio:

UnicodeString testString(testChars, "utf-8"); 
+0

Wow, grazie Remy, questo era qualcosa che non avevo nemmeno preso in considerazione, ho intenzione di sperimentare il tuo suggerimento per risolvere il mio problema con speranza prima di accettare. –