PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : UTF-8 in C++


rotalever
2007-07-19, 16:03:17
Ich hab schon mal bei Google und Co. gesucht aber nicht wirklich was gefunden. Mein Ziel ist es UTF8 Zeichenketten im Programmm zu speichern (vermutlich als \0 terminiertes char Array.). Zudem möchte ich Teile des UTF8-Strings aus einem größeren herausholen. Und an beliebiger Position andere UTF8-Strings einfügen.

Ich muss mir also im Endeffekt einen Einfachen UTF8-Parser bauen der sowas unterstützt wie: springezumnächstenZeichen() und gibmiraktuelleszeichen().

Auf Wikipedia steht wie UTF8 aufgebaut ist. Zum parsen müsste ich also mit den Bits rumspielen. Wie stellt man sowas am geschicktesten an? Also wie erkenne ich zum Beispiel am besten, wie viele Bytes das nächste Zeichen lang ist.
Dekodiert ist diese Länge ja durch
{n einsen}0{rest vom byte}
Extrahiert man da jetzt irgendwie die Bits, oder macht man ein paar < > Vergleiche oder wie? Habe leider nicht so viel Ahnung von diesen bits.

Bei den möglichen restlichen Bytes muss ich im Prinzip dann nur noch prüfen, ob sie die 01 am Anfang haben, also korrekt sind. Im Prinzip also wieder ein paar Bits extrahieren oder gibts da was besseres?

Wenn ich dann ein fertiges Zeichen habe speichere ich die Bytefolge einfach in einem Array ab und fertig. Die Bibliotheken mit denen ich dann interagiere regeln den Rest (freetype).

Ich muss halt im Prinzip nur das Einfügen, Löschen und Auslesen von Zeichen aus einem UTF8 string programmieren.

ManuelCalavera
2007-07-19, 16:20:54
Ist das ne Aufgabe? Sonst nimm einfach nen std::wstring

rotalever
2007-07-19, 16:34:19
Ist das ne Aufgabe? Sonst nimm einfach nen std::wstring
Nein ist keine Aufgabe.
wstring? Ist das nicht so ein 16-bit/32-bit kram? Wenn ich dann eine C-library habe, die UTF8 möchte (afaik will das freetype2) und das userinterface eben auch UTF8 sein soll, weil das vernünftig ist, dann müsste ich ja ständig umwandeln oder nicht?

Zumindest schien mir wstring sowas zu sein.

Coda
2007-07-19, 16:46:34
Die meisten Programme benützen wirklich nur die unter 16 bit von Unicode mit std::wstring bzw. wchar_t

Neomi
2007-07-19, 16:55:42
Hier mal eine Schnellversion zum parsen eines UTF-8 Strings. Wenn du die Zeichen mitzählst (wobei das bei zusammengesetzten Zeichen wieder schwieriger wird), kannst du deine Stringoperationen durchführen.

void ParseUTF8(char *pszText)
{
unsigned char *pszChar = (unsigned char*) pszText;

// Folgebytes am Anfang überspringen, unnötig bei garantiert validem UTF-8 String

while ((*pszChar & 0xC0) == 0x80)
pszChar++;

while (*pszChar != '\0')
{
unsigned long c = *pszChar++;

if ((c & 0x80) != 0)
{
int Count = 0; // 1 nur unter der Annahme, daß pszText ein valider UTF-8 String ist

while ((c & (0x40 >> Count)) != 0)
Count++;

// Prüfung auf zulässige Zahl an Folgebytes

if ((Count < 1) || (Count > 3))
{
// Fehler, kein valides UTF-8
}

// Bits ausmaskieren, die nicht zum Zeichen gehören

c &= 0x3F >> Count;

while (Count-- > 0)
{
// Prüfung auf gültiges Folgebyte

if ((*pszChar & 0xC0) != 0x80)
{
// Fehler, kein valides UTF-8
}

// die unteren 6 Bit vom Folgebyte anhängen

c = (c << 6) | (*pszChar++ & 0x3F);
}
}

// ein entpacktes Zeichen in c, pszChar zeigt auf nächstes Zeichen
}

return;
}

rotalever
2007-07-19, 17:22:19
Hier mal eine Schnellversion zum parsen eines UTF-8 Strings. Wenn du die Zeichen mitzählst (wobei das bei zusammengesetzten Zeichen wieder schwieriger wird), kannst du deine Stringoperationen durchführen.
[...]

Danke! Damit kann ich was anfangen. Bei Bit-Operationen hab ich noch ein bisschen wenig Erfahrung, deshalb komme ich nicht darauf, wie man es machen könnte, aber Verstehen tu ich es jetzt.

Was meinst Du mit zusammengesetzten Zeichen?

Neomi
2007-07-19, 18:25:45
Was meinst Du mit zusammengesetzten Zeichen?

Du kennst doch bestimmt Dead Keys, oder? Wenn du é haben willst, drückst du zuerst ´ und dann e, das wird dann normalerweise zu einem Zeichen zusammengefaßt. Non spacing Characters tun genau das gleiche, nur liegen die als separate Zeichen im Speicher und bilden dann zusammengesetzte Zeichen. Dann gibt es da natürlich noch diverse Steuerzeichen, bei bidirektionalen Sprachen soll das ja ganz schlimm sein.

Auch mit einer Kodierung, bei der jedes "Zeichen" eine feste Menge an Bytes belegt, ist nicht sichergestellt, daß die Menge an Zeichen identisch zur Menge an "Zeichen" ist.

rotalever
2007-07-19, 18:38:53
Du kennst doch bestimmt Dead Keys, oder? Wenn du é haben willst, drückst du zuerst ´ und dann e, das wird dann normalerweise zu einem Zeichen zusammengefaßt. Non spacing Characters tun genau das gleiche, nur liegen die als separate Zeichen im Speicher und bilden dann zusammengesetzte Zeichen. Dann gibt es da natürlich noch diverse Steuerzeichen, bei bidirektionalen Sprachen soll das ja ganz schlimm sein.

Auch mit einer Kodierung, bei der jedes "Zeichen" eine feste Menge an Bytes belegt, ist nicht sichergestellt, daß die Menge an Zeichen identisch zur Menge an "Zeichen" ist.

Dead keys und so ist mir ein Begriff und dass zum Beispiel die Eingabe bei Chinesisch sehr viel komplizierter ist auch. Aber das hat ja nur etwas mit der Eingabe zu tun. Ich meine wenn man eine Eingabe liest, dann liest man die ja ggf. erst in einen Puffer, wenn zum Beispiel ´ eingelesen wurde, um zu warten, was die nächste TASTE ist. Im Endeffekt kommt dabei dann aber doch ein Zeichen heraus. Sprich é ist ein Zeichen oder ´ oder aber auch 找. Und mit der Eingabe hat das UTF ja noch nichts zu tun. Ich möchte ja im Prinzip nicht anderes als "Fertige" Strings zu verarbeiten.

Neomi
2007-07-19, 20:59:26
Ich möchte ja im Prinzip nicht anderes als "Fertige" Strings zu verarbeiten.

Schon klar. Ich wollte ja auch nur anmerken, daß du dich leider nicht auf Zeichenzahl = "Zeichen"zahl verlassen kannst. Auch nicht in "fertigen" Strings.

rotalever
2007-07-19, 21:27:48
Schon klar. Ich wollte ja auch nur anmerken, daß du dich leider nicht auf Zeichenzahl = "Zeichen"zahl verlassen kannst. Auch nicht in "fertigen" Strings.
Hmm, dann blick ich wohl überhaupt nicht mehr durch. Ich dachte durch Unicode seien alle Buchstaben als ein Zeichen abgedeckt? Heißt das jetzt, dass ich in einem Text einer beliebigen Sprache auch solche Doppelzeichigen Buchstaben habe, oder wie?

Neomi
2007-07-19, 21:41:47
Ja, Buchstaben mit zwei Zeichen (und schlimmer: mehr als zwei) können vorkommen, auch mit Unicode. Aber man kann das scheinbar verhindern. Das hier dürfte interessant für dich sein, falls das zum Problem wird:
http://unicode.org/reports/tr15/

rotalever
2007-07-19, 22:20:15
Ja, Buchstaben mit zwei Zeichen (und schlimmer: mehr als zwei) können vorkommen, auch mit Unicode. Aber man kann das scheinbar verhindern. Das hier dürfte interessant für dich sein, falls das zum Problem wird:
http://unicode.org/reports/tr15/
Ich werde das jetzt einfach mal "übersehen" und soll es mal Probleme geben werde ich mich dann wohl der Seite widmen;).