2016-06-26 14 views
0

Lua hat eine Funktion utf8.len() benannt, die auf einem const char * arbeitet und führt die folgenden gemäß der Dokumentation:Zählen Anzahl von Zeichen in einem WCHAR String

Gibt die Anzahl der UTF-8-Zeichen in string s https://www.lua.org/manual/5.3/manual.html#6.5

Ich arbeite mit einer angepassten Version von Lua, die mit der Win32-API verbunden ist. Immer wenn ich eine UTF-8-Zeichenfolge an das Win32-Back-End meiner App übergeben muss, konvertiere ich es von UTF-8 zu WCHAR mit MultiByteToWideChar().

nun für eine Funktion, die ich bin auf der Suche, die genau die gleiche wie Lua utf8.len() Funktion tut, aber nimmt eine UTF-16 WCHAR* Zeichenfolge anstelle einer UTF-8 const char* String. Bitte fragen Sie mich nicht nach irgendwelchen Unicode-Feinheiten und terminologischen Diskussionen. Mir wurde bereits gesagt, dass der Begriff Zeichen ist sehr mehrdeutig, wenn über Unicode sprechen, aber die Lua-Dokumentation verwendet genau diesen Begriff (siehe oben). Also was ich will, ist eine Funktion, die genau das gleiche wie Lua's utf8.len() tut, aber auf einem WCHAR* anstelle von const char * ... unabhängig davon, was die Lua Autoren tatsächlich von Zeichen. Ich möchte nur eine Funktion haben, die mir genau die gleiche Anzahl wie utf8.len() gibt, aber arbeitet auf einer UTF-16 WCHAR* Zeichenfolge, die von einer UTF-8-Zeichenfolge von MultiByteToWideChar() generiert wird.

Ich hoffe, die Frage ist nun genug endlich klar genug ist ...

Eine letzte Anmerkung: Ich möchte, wenn möglich mit externen Bibliotheken wie ICU vermeiden. Win32-API-Lösungen werden bevorzugt.

+1

Sie fragen nach zwei verschiedenen Dingen: * Codepunkte * und * Zeichen *. Der Begriff * character * ist bei der Verwendung von Unicode sehr mehrdeutig. Es könnte Codepunkt so viel wie Graphem-Cluster bedeuten. Um was bitten Sie? – IInspectable

+1

Als Nebenbemerkung: Es gibt keinen 'TSTR'-Typ im Windows SDK. Sie beziehen sich wahrscheinlich auf 'TCHAR' und' TCHAR' und 'wcslen()' sind nicht kompatibel. Die erste repräsentiert entweder ein "char" oder "wchar_t", abhängig von den Präprozessorsymbolen. Letzteres funktioniert ausschließlich mit 'const wchar_t * '. – IInspectable

+1

'TCHAR' war nützlich, wenn wir für Windows 95/98/ME und Windows NT kodieren wollten. Ersteres unterstützte Unicode nicht. Aber für 10 Jahre war das zumindest nicht relevant. Sie interessieren sich für UTF-16. Also benutze 'wchar_t' und verwandte. Verwenden Sie nicht 'TCHAR'. Was Ihre Frage betrifft, müssen Sie besser definieren, was Sie mit einem * Zeichen * meinen. Können Sie bitte eine genaue Definition geben? –

Antwort

1

Betrachtet man the Lua utf8 source code, utf8.len() zählt nur die Anzahl der Codepunkte, so (zum Beispiel) Kombinieren von Zeichen würde separat gezählt werden. wcslen() ist dann der Weg zu gehen.

Sie sollten jedoch beachten, dass, wenn die Zeichenfolge enthält Zeichen außerhalb der BMP (U + 10000 oder höher; Emoji, zum Beispiel), wcslen() kann nicht die gleichen wie utf8.len() zurück. Dies liegt daran, dass UTF-16 diese nicht mit einem einzelnen Codepunkt darstellen kann. Stattdessen muss er den Codepunkt in zwei spezielle Codepunkte aufteilen, die zusammen Ersatzpaare heißen. Wenn Sie ein Ersatzpaar als einen einzigen Codepunkt behandeln müssen, müssen Sie diese Längenschleife selbst schreiben.