2013-09-28 14 views
33

Da quello che ho capito, un char è sicuro di caratteri ASCII casa mentre char16_t e char32_t sono sicuri da personaggi casa da unicode, uno per la varietà a 16 bit e un altro per la varietà a 32 bit (dovrei aver detto "a" anziché "il"?). Ma poi mi chiedo quale sia lo scopo alla base dello wchar_t. Dovrei mai usare quel tipo nel nuovo codice, o è semplicemente lì per supportare il vecchio codice? Qual era lo scopo di wchar_t nel vecchio codice se, da quello che ho capito, le sue dimensioni non avevano alcuna garanzia di essere più grandi di un char? Il chiarimento sarebbe carino!char wchar_t vs vs vs char16_t char32_t (C++ 11)

risposta

39

char è per unità di codice a 8 bit, char16_t è per unità di codice a 16 bit e char32_t per unità di codice a 32 bit. Ognuno di questi può essere usato per 'Unicode'; UTF-8 utilizza unità di codice a 8 bit, UTF-16 utilizza unità di codice a 16 bit e UTF-32 utilizza unità di codice a 32 bit.


La garanzia fatta per wchar_t era che qualsiasi carattere supportato in un locale potrebbe essere convertito da char a wchar_t, e tutto ciò che la rappresentazione è stato utilizzato per char, sia esso più byte, codici turno, quello che hai, il wchar_t sarebbe un valore singolo, distinto. Lo scopo di questo era quello di poter manipolare le stringhe wchar_t proprio come i semplici algoritmi usati con ASCII.

Ad esempio, la conversione ascii in maiuscolo va come:

auto loc = std::locale(""); 

char s[] = "hello"; 
for (char &c : s) { 
    c = toupper(c, loc); 
} 

ma questo non sarà gestire la conversione di tutti i caratteri in UTF-8 a caratteri maiuscoli, o tutti in qualche altra codifica come Shift-JIS. La gente voleva essere in grado di internazionalizzare il codice in questo modo:

auto loc = std::locale(""); 

wchar_t s[] = L"hello"; 
for (wchar_t &c : s) { 
    c = toupper(c, loc); 
} 

Così ogni wchar_t è un 'carattere' e se si dispone di una versione maiuscola allora possono essere convertiti direttamente. Sfortunatamente questo non funziona davvero tutto il tempo; Ad esempio esistono stranezze in alcune lingue come la lettera tedesca ß dove la versione maiuscola è in realtà i due caratteri SS invece di un singolo carattere.

La gestione del testo internazionalizzata è intrinsecamente più difficile di ASCII e non può essere semplificata nel modo in cui sono stati progettati i progettisti di wchar_t. In quanto tale, wchar_t e caratteri larghi in genere forniscono poco valore.

L'unico motivo per usarli è che sono stati integrati in alcune API e piattaforme. Tuttavia, preferisco attenermi a UTF-8 nel mio codice anche durante lo sviluppo su tali piattaforme e solo per convertire i limiti dell'API in qualsiasi codifica richiesta.

+1

Mi piace il tuo commento e il commento di Kuhl, entrambi hanno informazioni uniche. Vorrei poter dare due assegni verdi. Dovrò pensarci su per decidere chi lo ottiene. Il protocollo standard sullo stackoverflow non fornisce alcun controllo in caso di parità? – user904963

+0

* "la lettera tedesca ß dove la versione maiuscola è in realtà i due caratteri SS" * - Non è abbastanza preciso. La versione maiuscola di "ß" è "ẞ" (U + 1E9E: Latin Capital Letter Sharp S). È stato introdotto con Unicode 5.1 (vedere [Personalizzazione delle operazioni di rivestimento] (http://unicode.org/versions/Unicode5.1.0/#Tailored_Casing_Operations) come riferimento). Mentre il case Unicode predefinito fa maiuscole "ß" a "SS", questa non è la versione maiuscola. – IInspectable

+0

@Impostabile L'uso di "SS" non è un'invenzione dell'algoritmo del casing Unicode. Si basa sull'utilizzo effettivo. L'uso di "SS" e "SZ" è stata una pratica comune e gli algoritmi Unicode sono stati progettati per rispettarlo. Dalla documentazione Unicode a cui fai il link "In particolare, i caratteri maiuscoli sono intesi per rappresentazioni tipografiche di segnaletica e titoli maiuscoli, e altri ambienti in cui gli utenti richiedono che i taglienti siano conservati in maiuscolo. ** In generale, tale utilizzo è raro ** ". – bames53

17

Il tipo wchar_t è stato inserito nello standard quando Unicode ha promesso di creare una rappresentazione a 16 bit. La maggior parte dei fornitori sceglie di creare 3223 bit ma un grande fornitore ha scelto di renderlo 16 bit. Poiché Unicode utilizza più di 16 bit (ad es. 20 bit) si è ritenuto che dovremmo avere tipi di caratteri migliori.

L'intento di char16_t è rappresentare UTF16 e char32_t è pensato per rappresentare direttamente caratteri Unicode. Tuttavia, sui sistemi che utilizzano wchar_t come parte della loro interfaccia fondamentale, sarai bloccato con wchar_t. Se non sei vincolato, utilizzerei personalmente char per rappresentare Unicode utilizzando UTF8. Il problema con char16_t e char32_t è che non sono completamente supportati, nemmeno nella libreria standard di C++: ad esempio, non ci sono flussi che supportano questi tipi direttamente e funziona di più del semplice istanziamento del flusso per questi tipi.

+0

È la mancanza di supporto per 'char16_t' e' char32_t' nello standard a causa dello standard che non dichiara tale supporto o è dovuto al fatto che i tipi sono nuovi, il che significa che il supporto arriverà con il tempo? – user904963

+0

@ user904963: la revisione corrente non impone nomi per le versioni 'char16_t' e' char32_t'. Sembra che imponga le faccette necessarie, tuttavia, il che significa che i flussi potrebbero essere utilizzati. Non ho visto proposte che migliorino il supporto, ma ciò non significa che il comitato si opponga all'aggiunta di supporto, ad esempio, potrebbe venire. –