Wie lese ich die UTF-8 Zeichen per pointer?
Nehme an, dass ich UTF-8-Inhalte im Speicher gespeichert, wie kann ich Lesen Sie die Zeichen mit einem Zeiger? Ich nehme an, ich brauche die Uhr für das 8. bit, das angibt, dass eine multi-byte-Zeichen, aber wie genau schalte ich die Zeichenfolge in einen gültigen Unicode-Zeichen? Auch ist wchar_t
den richtigen Typ zu speichern eine einzelne Unicode-Zeichen?
Dies ist, was ich im Sinn haben:
wchar_t readNextChar (char*& p)
{
wchar_t unicodeChar;
char ch = *p++;
if ((ch & 128) != 0)
{
//This is a multi-byte character, what do I do now?
//char chNext = *p++;
//... but how do I assemble the Unicode character?
...
}
...
return unicodeChar;
}
- Es macht keinen Sinn, zu sagen, das "die Breite der Unicode-Zeichen". Sie müssen sich für eine Codierung. Je nach Plattform ist die
wchar_t
sein könnten unterschiedlicher Größe. Auf einem Unix-artigen OS ist es in der Regel 32bit, so können Sie speichern in UTF-32 codierte Unicode-Zeichen, bei Windows ist dies 16bit, so dass es UTF-16 codierte Unicode-Zeichen. - Neben der Rückkehr der Breite Charakter, Ihre
readNextChar
Funktion muss Informationen, um richtig zu aktualisierenp
. UTF-8 (oder UTF-16, für diese Angelegenheit) sind variable-Länge-Kodierungen und Ihr Gesprächspartner können nicht annehmen, dass eine Konstante oder einfaches Inkrementieren der Zeiger.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Haben Sie zum Dekodieren von UTF-8-bit-Muster, um seine nicht-codierte UTF-32-Darstellung. Wenn Sie möchten, dass die eigentliche Unicode-codepoint, müssen Sie verwenden ein 32-bit-Datentyp.
Unter Windows
wchar_t
ist NICHT groß genug, als es nur 16-bit. Verwenden Sie eineunsigned int
oderunsigned long
statt. Verwendenwchar_t
nur beim Umgang mit UTF-16 codeunits statt.Auf anderen Plattformen
wchar_t
ist in der Regel 32bit. Aber beim schreiben portablen code, sollten Sie bleiben Weg vonwchar_t
außer wenn absolut notwendig (wiestd::wstring
).Versuchen, so etwas wie dieses:
wchar_t
ist nicht definiert. Auf GCC (zumindest auf Linux)wchar_t
ist 32bit, so würde es sicherlich genug zu halten, Unicode-Zeichen ohne multi-byte-Codierung.switch
- Anweisung bis zu dem dieseqlen
variable festgelegt wird. Vielleicht wäre das gut für die original-code zu, um sich mehr lesbar.:)
u8""
literal verwendetconst char
Elemente, die so einfach aktualisieren Sie den code zum Durchlaufen der string mit einemconst char*
Zeiger anstelle eineschar*
Zeiger. Natürlich, wenn Sie mitu8""
dann sind Sie mit C++11 oder höher, und es gibt bessere Möglichkeiten zum Umgang mit UTF-8.F0 9F 98 80
, die die korrekten UTF-8-Sequenz für U+1F600 GRINSENDE GESICHT. Ich habe eingestellt das code handle richtig. Es war nur ein Logik-Fehler, wieIS_IN_RANGE()
wurde angewendet.Hier ist eine schnelle makro, die zählen, die UTF-8-bytes
Dies wird helfen, Sie erkennen die Größe der UTF-8-Zeichen-für eine einfachere Analyse.
Wenn Sie brauchen, um zu Dekodieren, UTF-8, die Sie tun müssen, entwickeln Sie eine UTF-8-parser. UTF-8 ist eine variable-Länge-Kodierung (1 bis 4 Byte), so dass Sie wirklich haben, um schreiben Sie einen parser, der konform ist mit dem standard : sehen wikipedia zum Beispiel.
Wenn Sie nicht wollen, schreiben Sie Ihre eigenen parser, schlage ich eine Bibliothek. Sie werden feststellen, dass in der glib zum Beispiel (ich personnaly verwendet haben, Glib::ustring, die C++ - wrapper für glib), aber auch in jedem guten Allzweck-Bibliothek.
Edit:
Ich denke, dass C++0x wird enthalten UTF-8-Unterstützung, aber ich bin kein Spezialist...
my2c
Unter Linux, ja. Unter Windows
wchar_t
entspricht ein UTF-16-code-unit, das ist nicht unbedingt ein Charakter.Kommende C++0x standard wird die
char16_t
undchar32_t
Arten die Darstellung von UTF-16 und UTF-32.Wenn auf einem system, wo
char32_t
ist nicht verfügbar, und diewchar_t
unzureichend ist, verwenden Sieuint32_t
zum speichern von Unicode-Zeichen.Dies ist meine Lösung in reinem ANSI-C, einschließlich einer unit-test für die Ecke Fälle.
Beachten Sie, dass
int
muss mindestens 32 bit breit. Andernfalls müssen Sie zum ändern der definitioncodepoint
.static
. (4) als ich erklärte, dass die loop-variable mit einer Funktion-breiten Anwendungsbereich. Aber auf der anderen Seite, ich habe nicht erfinden komischen Typ-Namen (u_long
,u_char
) und verwendet Sie uneinheitlich (u_char
vs.uchar
) und ohne Deklaration. Ich habe es auch geschafft komplett zu vermeiden jede Art cast (das ist die akzeptierte Antwort verwendet eine Menge, und das ist im C-Stil, auch.)pstart
undend
sonst sehr ähnlich Aussehen auf der rufenden Seite.from_utf8(start, end, &cp)
. Wie sollte jemand vermuten, dassstart
wird geändert undend
nicht?