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 24 4ist 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.