2013-09-07 9 views
6

Se ho capito bene, è possibile utilizzare sia stringa che stringa per memorizzare testo UTF-8.std :: string e Unicode codificato UTF-8

  • Con char, caratteri ASCII prendono un singolo byte, alcuni caratteri cinesi prendono 3 o 4, ecc Il che significa che str[3] non necessariamente puntare al 4 ° carattere.

  • Con wchar_t stessa cosa, ma la quantità minima di byte utilizzati per personaggi è sempre 2 (invece di 1 per char), e un carattere largo 3 o 4 byte avrà 2 wchar_t.

Giusto?

Quindi, cosa succede se voglio utilizzare string::find_first_of() o string::compare(), ecc con una stringa così stranamente codificata? Funzionerà ? La classe string gestisce il fatto che i caratteri hanno una dimensione variabile? O dovrei usarli solo come semplici array di byte senza funzionalità, nel qual caso preferirei utilizzare un buffer wchar_t[].

Se std::string non gestisce che, seconda domanda: esistono librerie forniscono classi stringa che possa gestire che codifica UTF-8 in modo che str[3] effettivamente punti al 3 ° carattere (che sarebbe un array di byte da lunghezza da 1 a 4)?

+0

Si noti che anche se 'str [3]' era il quarto punto di codice, non è necessariamente il quarto carattere percepito dall'utente. – delnan

+1

@delnan _Ok scusate (ho appena scelto un articolo di esempio su wchar_t, Windows e UTF-16). Dato che era troppo tardi per modificare ho cancellato il commento, e qui è tornata la parte senza il link "controverso": _ Penso che la dimensione di 'wchar_t' sia definita dall'implementazione, quindi _non_ sempre 2 byte. Inoltre (IIRC) Windows lo usa per memorizzare qualcosa come UTF-16, non UTF-8. Vedi http://en.wikipedia.org/wiki/Wide_character –

risposta

5

Stai parlando di Unicode. Unicode utilizza 32 bit per rappresentare un carattere. Tuttavia dal momento che sta sprecando memoria ci sono codifiche più compatte. UTF-8 è una di queste codifiche. Presuppone che si stiano utilizzando unità di byte e mappa i caratteri Unicode a 1, 2, 3 o 4 byte. UTF-16 è un altro che utilizza le parole come unità e mappa i caratteri Unicode in 1 o 2 parole (2 o 4 byte). È possibile utilizzare entrambe le codifiche sia con stringa che con wchar_t. UTF-8 tende ad essere più compatto per testo/numeri in inglese.

Alcune cose funzioneranno indipendentemente dalla codifica e dal tipo utilizzato (confronta). Tuttavia tutte le funzioni che necessitano di capire un personaggio verranno interrotte. Il quinto carattere non è sempre la quinta voce nell'array sottostante. Potrebbe sembrare che funzioni con determinati esempi ma alla fine si romperà. string :: compare funzionerà ma non aspettarti di ottenere l'ordine alfabetico. Questo dipende dalla lingua. string :: find_first_of funzionerà per alcuni ma non per tutti. La stringa lunga probabilmente funzionerà solo perché è lunga, mentre quelli più brevi potrebbero essere confusi dall'allineamento dei caratteri e generare errori molto difficili da trovare.

La cosa migliore è trovare una libreria che la gestisca per te e ignorare il tipo sottostante (a meno che tu non abbia dei validi motivi per sceglierne uno o l'altro).

+0

Grazie per la risposta. – Virus721

+5

* Unicode utilizza 32 bit per rappresentare un carattere. * => Dipende in realtà da ciò che si chiama un carattere. Unicode definisce Code Points (interi) e Graphemes (sequenze di interi, generalmente di dimensione 1), e le persone tendono ad associare "character" con "grapheme" perché è l'entità visiva che appare sullo schermo. –

+0

_Unicode utilizza 32 bit per rappresentare un carattere._ Questo non è corretto! Unicode ** non ** usa una quantità qualsiasi di bit per rappresentare un personaggio. Unicode è puramente astratto. Assegna un numero a ciascun personaggio. Non impone quanti bit rappresentare quel personaggio. Le codifiche non sono modi "più compatti" per rappresentare i personaggi, sono ** i modi per rappresentare i personaggi. Vedi https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-adsolutely-positively-must-know-about-unicode-and-character-sets-no-excuses/ – Len

-1

Lei ha ragione per quelli:
... Il che significa che str [3] non necessariamente puntare al 4 ° carattere ... usarli solo come manichino di funzionalità meno array di byte ...

una stringa di C++ può gestire solo caratteri ascii. Questo è diverso dalla stringa di Java, che può gestire i caratteri Unicode. È possibile memorizzare il risultato della codifica (byte) di caratteri cinesi in stringa (char in C/C++ è solo byte), ma ciò non ha senso poiché stringa tratta i byte come caratteri ascii, quindi non è possibile utilizzare la funzione stringa per elaborarla.
wstring può essere qualcosa che ti serve.

C'è qualcosa che dovrebbe essere chiarito. UTF-8 è solo un metodo di codifica per i caratteri Unicode (trasformando i caratteri da/a formato byte).

+0

Grazie per la risposta. Quello che volevo sapere è quali metodi della classe string funzionano ancora quando si utilizza un testo con codifica UTF-8. – Virus721

+0

-1 'std :: string' memorizza' char's. Ma questo non significa che sia limitato ad ASCII, significa solo che non sa nulla delle codifiche, quindi puoi usarlo per qualsiasi codifica (e di conseguenza svuota tutto se non stai attento). E la stringa Java è un array UTF-16, quindi 'str [3]' non è necessariamente il quarto punto di codice. – delnan

+0

@delnan Si prega di abbassare il voto dopo aver esaminato completamente la mia risposta. Ho dichiarato questo "È possibile memorizzare i risultati di codifica (byte) di caratteri cinesi in stringa (char in C/C++ è solo byte), ma ciò non ha senso poiché stringa tratta i byte come caratteri ascii, quindi non è possibile utilizzare la funzione stringa per elaborarlo. "Ho detto che" una stringa di C++ può gestire solo caratteri ascii ". non "una stringa di C++ può solo memorizzare caratteri ascii". MANIGLIA è diversa da STORE. le funzioni di stringa saranno prive di significato quando lo si utilizza per memorizzare byte, ecco perché ho usato HANDLE. Grazie. – JackyZhu

Problemi correlati