Wie viele Bits ist wchar_t
in wchar.h
in C-Sprache definiert?
Hast du gedacht, es waren 16 Bit? (Ich dachte auch) Eigentlich kommt es auf die Umgebung an. Manchmal sind es nicht 16 Bit.
** * Der Einfachheit halber werden wir hier keine Ersatzpaare betrachten. ** **.
main.c
#include <stdio.h>
#include <wchar.h>
int main() {
wchar_t *s = L"ABCD";
printf("%d %d\n", wcslen(s), sizeof(s[0]));
return 0;
}
Wenn ich dies mit gcc kompiliere, ist das Ergebnis
4 2
4 4
ist geworden.
L ""
, das breite Zeichen darstellt, und wcslen ()
, das die Anzahl der Zeichen zählt, werden aufeinander abgestimmt, aber die Realität von wchar_t
beträgt 16 Bit für das erstere und das letztere für das letztere. Unterscheidet sich von 32-Bit.
Nehmen wir an, dass die von außen angegebenen Unicode-Zeichenfolgendaten als nullterminierte Zeichenfolge mit 16 Bit pro Zeichen (UTF-16) ausgedrückt werden. Wenn Sie versuchen, die Zeichenfolge und die Anzahl der Zeichen auszugeben, sieht es beispielsweise wie das folgende Programm aus.
#include <stdio.h>
#include <wchar.h>
int main() {
char data[] = {0x40, 0x00, 0x41, 0x00, 0x42, 0x00, 0x00, 0x00}; //Angenommen, dies ist gegeben
wchar_t *s = (wchar_t *)data;
printf("%ls %d\n", s, wcslen(s));
return 0;
}
Dies ist jedoch in einer Umgebung der Fall, in der wchar_t
16 Bit beträgt.
@AB 3
Wird wie erwartet angezeigt, verhält sich jedoch in einer 32-Bit-Umgebung unerwartet.
In C ++ 11 wurde ein Typ namens "char16_t" als Datentyp erstellt, der ein Zeichen von UTF-16 darstellt (ausgenommen Ersatzpaare). In ähnlicher Weise wäre ein 32-Bit-Zeichen "char32_t". Außerdem wurde die Notation für Zeichenfolgenliterale in UTF-16 / UTF-32 hinzugefügt.
Das Beispiel am Anfang scheint wie folgt geschrieben zu sein (obwohl es C ++ ist).
main.cpp
#include <stdio.h>
#include <string>
using namespace std;
int main() {
char16_t s[] = u"ABCD"; // UTF-Literal mit 16 Zeichenfolgen
printf("%d %d\n", char_traits<char16_t>::length(s), sizeof(s[0]));
return 0;
}
Geben Sie C ++ 11 in den Kompilierungsoptionen an.
terminal
g++ -std=c++11 main.cpp
4 2
wird unabhängig von der Größe von wchar_t
ausgegeben.
Im Gegensatz zu wchar_t
hat char16_t
keine Ausgabe in der Funktion printf ()
.
Stattdessen sieht es so aus. (Speichern Sie den Quellcode als UTF-8)
#include <string>
#include <codecvt>
#include <locale>
#include <iostream>
using namespace std;
int main() {
char16_t s[] = u"AIUEO";
wstring_convert<codecvt_utf8<char16_t>, char16_t> cv;
cout << cv.to_bytes(s) << endl;
return 0;
}
Die folgenden Bedingungen gelten jedoch für die Verwendung von "codecvt_utf8". → codecvt_utf8 --cpprefjp --C ++ Japanische Referenz
Der Typ char
, der ein Zeichen in Java darstellt, ist 16 Bit.
Wenn Sie beispielsweise in JNI (Java Native Interface) die durch UTF-16 (Nullterminierung) dargestellten Zeichenfolgendaten als Java-Typ "String" ("jstring") zurückgeben möchten, die Anzahl der Zeichen Ich bin süchtig danach, mit wcslen
zu zählen.
C++Code
// jbyteArray (byte[])Angesichts des Typarguments arg
jbyte *arg_ptr = env->GetByteArrayElements(arg, NULL);
//wcslen kann zu unerwarteten Ergebnissen führen
jstring ret_string = env->NewString((jchar *)arg_ptr, wcslen((wchar_t *)arg_ptr));
env->ReleaseByteArrayElements(arg, arg_ptr, 0);
Ist es so als Gegenmaßnahme? (Notieren Sie sich die erforderliche Header-Deklaration und using namespace std;
)
jstring ret_string = env->NewString((jchar *)arg_ptr, char_traits<char16_t>::length((char16_t *)arg_ptr));
Wenn Sie nur die Länge der nullterminierten Zeichenfolge herausfinden möchten, können Sie dies selbst tun, indem Sie ...
Es gibt eine Bibliothek namens "ctypes" zum Aufrufen von gemeinsam genutzten C / C ++ - Bibliotheken (.dll, .so) aus Python. Auch hier können Sie süchtig danach sein, ein Array von Unicode-Zeichen aus einer Folge von Bytes zu erstellen und zu bearbeiten oder es an eine andere Funktion zu übergeben.
Python
import ctypes
wstr = ctypes.create_unicode_buffer(u"AIUEO")
print(ctypes.sizeof(wstr))
Wenn wchar_t
eine 16-Bit-Umgebung ist, wird 12
ausgegeben, und wenn es sich um eine 32-Bit-Umgebung handelt, wird 24
ausgegeben.
Die "Umgebung" hier ist wie die Umgebung des Compilers, der zum Erstellen von Python verwendet wird.
Tatsächlich ist "create_unicode_buffer ()" selbst möglicherweise nicht sehr nützlich.
Beim Umgang mit Windows-APIs wäre es hilfreich, mit Argumenten vom Typ wchar_t *
umzugehen.
wchar_t
Ich habe Angst. wcslen
Ich habe Angst.
Ich bete, dass mehr Menschen wie ich nicht geleckt und verängstigt werden.