Nach einer verwandten Frage möchte ich nach den neuen Zeichen- und Zeichenfolgenliteraltypen in C ++ 11 fragen. Es scheint, dass wir jetzt vier Arten von Zeichen und fünf Arten von String-Literalen haben. Die Zeichentypen:
char a = '\x30'; // character, no semantics
wchar_t b = L'\xFFEF'; // wide character, no semantics
char16_t c = u'\u00F6'; // 16-bit, assumed UTF16?
char32_t d = U'\U0010FFFF'; // 32-bit, assumed UCS-4
Und die String-Literale:
char A[] = "Hello\x0A"; // byte string, "narrow encoding"
wchar_t B[] = L"Hell\xF6\x0A"; // wide string, impl-def'd encoding
char16_t C[] = u"Hell\u00F6"; // (1)
char32_t D[] = U"Hell\U000000F6\U0010FFFF"; // (2)
auto E[] = u8"\u00F6\U0010FFFF"; // (3)
Die Frage ist: Sind die \x
/ \u
/ \U
Zeichenreferenzen mit allen Zeichenfolgentypen frei kombinierbar? Haben alle Zeichenfolgentypen eine feste Breite, dh die Arrays enthalten genau so viele Elemente, wie im Literal erscheinen, oder werden \x
/ \u
/ \U
Verweise auf eine variable Anzahl von Bytes erweitert? Haben u""
und u8""
Strings eine Codierungssemantik, z. B. kann ich sagen char16_t x[] = u"\U0010FFFF"
, und der Nicht-BMP-Codepunkt wird in eine UTF16-Sequenz mit zwei Einheiten codiert? Und ähnlich für u8
? Kann ich in (1) einsame Ersatzzeichen mit schreiben \u
? Ist schließlich eine der codierenden Zeichenfolgenfunktionen bekannt (dh sie sind zeichenbewusst und können ungültige Bytesequenzen erkennen)?
Dies ist eine offene Frage, aber ich möchte ein möglichst vollständiges Bild der neuen UTF-Codierungs- und Typfunktionen des neuen C ++ 11 erhalten.
u"\U0010FFFF"
in ein Ersatzpaar.Antworten:
Nein
\x
kann alles verwendet werden, aber\u
und\U
kann nur in Zeichenketten verwendet werden , die speziell UTF-codiert sind. Jedoch für jede UTF-codierte Zeichenfolge\u
und\U
kann nach Belieben verwendet werden.Nicht so wie du meinst.
\x
,,\u
und\U
werden basierend auf der Zeichenfolgencodierung konvertiert. Die Anzahl dieser "Codeeinheiten" (unter Verwendung von Unicode-Begriffen. Achar16_t
ist eine UTF-16-Codeeinheit) hängt von der Codierung der enthaltenen Zeichenfolge ab. Das Literalu8"\u1024"
würde eine Zeichenfolge erstellen, die 2char
s plus einen Nullterminator enthält. Das Literalu"\u1024"
würde eine Zeichenfolge erstellen, die 1char16_t
plus einen Nullterminator enthält.Die Anzahl der verwendeten Codeeinheiten basiert auf der Unicode-Codierung.
u""
Erstellt eine UTF-16-codierte Zeichenfolge.u8""
Erstellt eine UTF-8-codierte Zeichenfolge. Sie werden gemäß der Unicode-Spezifikation codiert.Absolut nicht. Die Spezifikation verbietet ausdrücklich die Verwendung der UTF-16-Ersatzpaare (0xD800-0xDFFF) als Codepunkte für
\u
oder\U
.Absolut nicht. Gestatten Sie mir, das umzuformulieren.
std::basic_string
behandelt keine Unicode-Codierungen. Sie können sicherlich UTF-codierte Zeichenfolgen speichern . Aber sie können denken nur von ihnen als Folge vonchar
,char16_t
oderchar32_t
; Sie können sie nicht als eine Folge von Unicode-Codepunkten betrachten, die mit einem bestimmten Mechanismus codiert sind.basic_string::length()
gibt die Anzahl der Codeeinheiten zurück, nicht die Codepunkte. Und offensichtlich sind die Zeichenfolgenfunktionen der C-Standardbibliothek völlig nutzlosEs ist jedoch zu beachten, dass "Länge" für eine Unicode-Zeichenfolge nicht die Anzahl der Codepunkte bedeutet. Einige Codepunkte kombinieren "Zeichen" (ein unglücklicher Name), die mit dem vorherigen Codepunkt kombiniert werden. So können mehrere Codepunkte einem einzelnen visuellen Zeichen zugeordnet werden.
Iostreams können tatsächlich Unicode-codierte Werte lesen / schreiben. Dazu müssen Sie ein Gebietsschema verwenden, um die Codierung anzugeben und sie ordnungsgemäß an den verschiedenen Stellen zu platzieren. Das ist leichter gesagt als getan, und ich habe keinen Code, der Ihnen zeigt, wie.
quelle
\x
kann nichts verwendet werden, z. B. funktioniert U + 1F984 nicht mit dem Präfix \ x\u
und\U
kann nicht mit ASCII-Steuerzeichen verwendet werden, zumindest in Clang.