2012-03-18 3 views
10

sviluppatori di software popolari e le aziende (Joel Spolsky, Fog Creek software) tendono ad usare wchar_t per caratteri Unicode stoccaggio durante la scrittura di codice C o C++. Quando e come si dovrebbe usare char e wchar_t rispetto alle buone pratiche di codifica?Corretto utilizzo dello storage stringa in C e C++

Sono particolarmente interessato a conformità POSIX durante la scrittura di software che sfrutta Unicode.

Quando si utilizza wchar_t, è possibile cercare caratteri in un array di caratteri di larghezza su una base per carattere o per-array-elemento:

/* C code fragment */ 
const wchar_t *overlord = L"ov€rlord"; 
if (overlord[2] == L'€') 
    wprintf(L"Character comparison on a per-character basis.\n"); 

Come si può confrontare byte Unicode (o caratteri) quando si utilizza char?

Finora il mio modo preferito di confronto tra stringhe e caratteri di tipo char in C spesso assomiglia a questo:

/* C code fragment */ 
const char *mail[] = { "ov€[email protected]", "ov€[email protected]" }; 
if (mail[0][2] == mail[1][2] && mail[0][3] == mail[1][3] && mail[0][3] == mail[1][3]) 
    printf("%s\n%zu", *mail, strlen(*mail)); 

scansioni questo metodo per l'equivalente di byte di un carattere Unicode. Il simbolo dell'euro Unicode occupa 3 byte. Pertanto è necessario confrontare tre byte dell'array di caratteri per sapere se i caratteri Unicode corrispondono. Spesso è necessario conoscere la dimensione del carattere o della stringa che si desidera confrontare e i bit che produce affinché la soluzione funzioni. Questo non sembra un buon modo di gestire Unicode. Esiste un modo migliore per confrontare stringhe e elementi di carattere di tipo char?

Inoltre, quando si utilizza wchar_t, come si può eseguire la scansione del contenuto del file con un array? La funzione fread non sembra produrre risultati validi.

+9

Unicode in C++: non utilizzare 'wchar_t', utilizzare una libreria Unicode corretta. –

+3

'tendono ad usare wchar_t per la codifica dei caratteri Unicode'. No; lo usano per il carattere Unicode _storage_, e c'è una grande differenza. –

+0

possibile duplicato di [std :: wstring VS std :: string] (http://stackoverflow.com/questions/402283/stdwstring-vs-stdstring) –

risposta

10

Se si sa che si tratta di unicode, né charwchar_t sono appropriati in quanto le loro dimensioni sono definite dal compilatore/dalla piattaforma. Ad esempio, wchar_t è 2 byte su Windows (MSVC), ma 4 byte su Linux (GCC). Gli standard C11 e C++ 11 sono stati un po 'più rigorosi e definiscono due nuovi tipi di caratteri (char16_t e char32_t) con prefissi letterali associati per la creazione di stringhe UTF- {8, 16, 32}.

Se è necessario archiviare e manipolare caratteri unicode, è necessario utilizzare una libreria progettata per il lavoro, in quanto né gli standard di lingua pre-C11 né quelli pre-C++ 11 sono stati scritti tenendo conto dell'unicode. Ci sono few to choose from, ma ICU è abbastanza popolare (e supporta C, C++ e Java).

+3

Anche C++ 11 è piuttosto leggero sulle cose Unicode. Oltre a richiedere alcuni tipi e conversioni standard tra utf8/16/32 non troverete nulla come confronto, confronto, normalizzazione, ecc. –

+0

Proprio come aggiunta, penso che C11 qui cerchi di essere sincronizzato con C++ 1 e introduce gli stessi nuovi tipi 'char ?? _ t'. –

+0

Sì, C11 è sincronizzato con C++ 11 per questi tipi/letterali. –

0

Sono particolarmente interessato a POSIX conformità durante la scrittura di un software che sfrutta Unicode.

In questo caso, probabilmente si vorrà utilizzare UTF-8 (con char) come tipo di stringa Unicode preferito.POSIX non ha molte funzioni per lavorare con wchar_t — che è principalmente una cosa di Windows.

Questo metodo esegue la scansione dell'equivalente in byte di un carattere Unicode. Il simbolo dell'euro Unicode occupa 3 byte. Pertanto è necessario confrontare tre byte di array di caratteri per sapere se i caratteri Unicode corrispondono. Spesso è necessario conoscere la dimensione del carattere o della stringa che si desidera confrontare con e i bit che produce affinché la soluzione funzioni.

No, non è così. Basta confrontare i byte. Iff la corrispondenza dei byte, le stringhe corrispondono. strcmp funziona altrettanto bene con UTF-8 come con qualsiasi altra codifica.

A meno che non si desideri eseguire una comparazione insensibile alle maiuscole o insensibile agli accenti, nel qual caso è necessaria una libreria Unicode corretta.

0

Non si dovrebbe mai confrontare mai byte, o anche punti di codice, per decidere se le stringhe sono uguali. Questo perché molte stringhe possono essere identiche dal punto di vista dell'utente senza essere identiche dalla prospettiva del punto di codice.