2013-09-07 3 views
6

Wenn ich es gut verstehe, ist es möglich, sowohl Zeichenfolge als auch wstring zu verwenden, um UTF-8 Text zu speichern.std :: string und UTF-8 codierte Unicode

  • Mit char, ASCII-Zeichen nehmen ein einzelnes Byte, einige chinesische Zeichen nehmen 3 oder 4, usw. Das bedeutet, dass str[3] nicht notwendigerweise auf das 4. Zeichen zeigen.

  • Mit wchar_t elbe, aber die minimale Menge der Bytes pro Zeichen verwendet wird, ist immer 2 (anstelle von 1 für char) und eine 3 oder 4 Byte breiten Zeichen wird 2 wchar_t nehmen.

Richtig?

Also, was, wenn ich string::find_first_of() oder , etc. mit solch einer seltsam kodierten Zeichenfolge verwenden möchte? Wird es funktionieren ? Behandelt die String-Klasse die Tatsache, dass Zeichen eine variable Größe haben? Oder sollte ich sie nur als Dummy-Feature-lose Byte-Arrays verwenden, in diesem Fall würde ich eher für einen wchar_t[] Puffer gehen.

Wenn das nicht behandelt, zweite Frage: Gibt es Bibliotheken, die String-Klassen bereitstellen, die diese UTF-8-Codierung verarbeiten können, sodass str[3] tatsächlich auf das dritte Zeichen zeigt (das wäre ein Byte-Array von Länge 1 bis 4))

+0

Beachten Sie, dass, auch wenn 'str [3]' der vierte Codepunkt war, dies nicht unbedingt das vierte vom Benutzer wahrgenommene Zeichen ist. – delnan

+1

@delnan _Ok Entschuldigung (Ich habe gerade einen Beispielartikel über wchar_t, Windows und UTF-16 ausgewählt). Da es für die Bearbeitung zu spät war, habe ich den Kommentar gelöscht, und hier ist wieder der Teil ohne den "umstrittenen" Link: _ Ich denke, dass die Größe von 'wchar_t' implementierungsdefiniert ist, also _nicht_ immer 2 Bytes. Außerdem (IIRC) Windows verwendet es, um etwas wie UTF-16, nicht UTF-8 zu speichern. Siehe http://en.wikipedia.org/wiki/Wide_character –

Antwort

5

Sie sprechen über Unicode. Unicode verwendet 32 ​​Bits, um ein Zeichen darzustellen. Da jedoch Speicher verschwendet wird, gibt es kompaktere Kodierungen. UTF-8 ist eine solche Codierung. Es geht davon aus, dass Sie Byte-Einheiten verwenden und Unicode-Zeichen auf 1, 2, 3 oder 4 Byte abbilden. UTF-16 ist ein weiterer, der Wörter als Einheiten verwendet und Unicode-Zeichen auf 1 oder 2 Wörter (2 oder 4 Bytes) abbildet. Sie können beide Codierungen mit String und wchar_t verwenden. UTF-8 ist tendenziell kompakter für englische Texte/Zahlen.

Einige Dinge funktionieren unabhängig von der verwendeten Codierung und dem verwendeten Typ (vergleichen). Jedoch werden alle Funktionen, die ein Zeichen verstehen müssen, gebrochen. Das fünfte Zeichen ist nicht immer der fünfte Eintrag im darunterliegenden Array. Es sieht vielleicht so aus, als würde es mit bestimmten Beispielen arbeiten, aber es wird irgendwann kaputt gehen. string :: compare funktioniert, erwartet aber keine alphabetische Sortierung. Das ist sprachabhängig. string :: find_first_of funktioniert für einige, aber nicht für alle. Lange Zeichenketten funktionieren wahrscheinlich nur, weil sie lang sind, während kürzere Zeichenketten durch die Zeichenausrichtung verwirrt werden und sehr schwer zu findende Fehler erzeugen.

Am besten ist es, eine Bibliothek zu finden, die es für Sie behandelt und den Typ darunter ignoriert (es sei denn, Sie haben gute Gründe, das eine oder andere auszuwählen).

+0

Vielen Dank für Ihre Antwort. – Virus721

+5

* Unicode verwendet 32 ​​Bits, um ein Zeichen darzustellen. * => Hängt wirklich davon ab, was Sie ein Zeichen nennen. Unicode definiert Code Points (Ganzzahlen) und Grapheme (Ganzzahlenfolgen, im Allgemeinen der Größe 1), und Menschen neigen dazu, "Zeichen" mit "Graphem" zu assoziieren, weil es die visuelle Entität ist, die auf dem Bildschirm erscheint. –

+0

_Unicode verwendet 32 ​​Bits, um ein Zeichen darzustellen._ Das ist falsch! Unicode verwendet ** nicht ** eine beliebige Anzahl von Bits, um ein Zeichen darzustellen. Unicode ist rein abstrakt. Es weist jedem Zeichen eine Nummer zu. Es legt nicht fest, wie viele Bits dieses Zeichen darstellen soll. Die Kodierungen sind keine "kompakteren" Arten, die Charaktere darzustellen, sie sind ** die Arten, die Charaktere darzustellen. Siehe https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolut-positiv-must-know-about-unicode-and-character-sets-no-excuses/ – Len

-1

Sie sind richtig für diejenigen:
... was bedeutet, dass str [3] nicht notwendigerweise auf das 4. Zeichen zeigen ... benutzen sie nur als Dummy-Funktion losen Byte-Arrays ...

Zeichenfolge von C++ kann nur Ascii-Zeichen verarbeiten. Dies unterscheidet sich von der Zeichenfolge von Java, die Unicode-Zeichen verarbeiten kann. Sie können das Enkodierungsergebnis (Bytes) chinesischer Zeichen in eine Zeichenfolge speichern (char in C/C++ ist nur Byte), aber dies ist bedeutungslos, da die Zeichenfolge nur die Bytes als ASCII-Zeichen behandelt, so dass Sie die Zeichenfolgenfunktion nicht verwenden können.
wstring kann etwas sein, das Sie brauchen.

Es gibt etwas, das geklärt werden sollte. UTF-8 ist nur eine Kodierungsmethode für Unicode-Zeichen (Umwandlung von Zeichen aus dem/in das Byte-Format).

+0

Danke für deine Antwort. Was ich wissen wollte, ist, welche Methoden der String-Klasse immer noch funktionieren würden, wenn ein UTF-8-kodierter Text verwendet würde. – Virus721

+0

-1 'std :: string' speichert' char's. Aber das bedeutet nicht, dass es auf ASCII beschränkt ist, es bedeutet nur, dass es nichts über Kodierungen weiß, also können Sie es für jede Kodierung verwenden (und folglich alles vermasseln, wenn Sie nicht vorsichtig sind). Und der Java-String ist ein UTF-16-Array, also ist 'str [3]' nicht unbedingt der vierte Code-Punkt. – delnan

+0

@delnan Bitte stimmen Sie ab, nachdem Sie meine Antwort vollständig durchgearbeitet haben. Ich habe dies festgestellt "Sie können das Enkodierungsergebnis (Bytes) von chinesischen Zeichen in eine Zeichenfolge speichern (char in C/C++ ist nur Byte), aber dies ist bedeutungslos als Zeichenfolge behandelt nur die Bytes als ASCII-Zeichen, so dass Sie keine Zeichenfolge Funktion verwenden können um es zu verarbeiten. "Ich sagte" Zeichenfolge von C++ kann nur ASCII-Zeichen verarbeiten. " nicht "Zeichenfolge von C++ kann nur ASCII-Zeichen speichern." HANDLE ist anders als STORE. String-Funktionen werden bedeutungslos, wenn Sie es nur zum Speichern von Bytes verwenden, deshalb habe ich HANDLE verwendet. Vielen Dank. – JackyZhu

2

Sie können Unicode nicht mit std :: string oder anderen Werkzeugen aus der Standardbibliothek behandeln. Verwenden Sie eine externe Bibliothek wie: http://utfcpp.sourceforge.net/

+0

Danke, ich werde es mir ansehen. – Virus721

Verwandte Themen