Zeichenfolgen- und Zeichenliterale (C++)

C++ unterstützt verschiedene Zeichenfolgen- und Zeichentypen und bietet Möglichkeiten Literalwerte dieser einzelnen Typen auszudrücken. In Ihrem Quellcode stellen Sie die Inhalte Ihrer Zeichen- und Zeichenfolgenliterale mit einem Zeichensatz dar. Universelle Zeichennamen und Escapezeichen ermöglichen es Ihnen, eine beliebige Zeichenfolge darzustellen, indem Sie nur den grundlegenden Quellzeichensatz verwenden. Ein unformatiertes Zeichenfolgenliteral ermöglicht es Ihnen, die Verwendung von Escapezeichen zu vermeiden, und kann verwendet werden, um alle Typen von Zeichenfolgenliteralen auszudrücken. Sie können auch Literale erstellen std::string , ohne zusätzliche Konstruktions- oder Konvertierungsschritte ausführen zu müssen.

#include <string>
using namespace std::string_literals; // enables s-suffix for std::string literals

int main()
{
    // Character literals
    auto c0 =   'A'; // char
    auto c1 = u8'A'; // char
    auto c2 =  L'A'; // wchar_t
    auto c3 =  u'A'; // char16_t
    auto c4 =  U'A'; // char32_t

    // Multicharacter literals
    auto m0 = 'abcd'; // int, value 0x61626364

    // String literals
    auto s0 =   "hello"; // const char*
    auto s1 = u8"hello"; // const char* before C++20, encoded as UTF-8,
                         // const char8_t* in C++20
    auto s2 =  L"hello"; // const wchar_t*
    auto s3 =  u"hello"; // const char16_t*, encoded as UTF-16
    auto s4 =  U"hello"; // const char32_t*, encoded as UTF-32

    // Raw string literals containing unescaped \ and "
    auto R0 =   R"("Hello \ world")"; // const char*
    auto R1 = u8R"("Hello \ world")"; // const char* before C++20, encoded as UTF-8,
                                      // const char8_t* in C++20
    auto R2 =  LR"("Hello \ world")"; // const wchar_t*
    auto R3 =  uR"("Hello \ world")"; // const char16_t*, encoded as UTF-16
    auto R4 =  UR"("Hello \ world")"; // const char32_t*, encoded as UTF-32

    // Combining string literals with standard s-suffix
    auto S0 =   "hello"s; // std::string
    auto S1 = u8"hello"s; // std::string before C++20, std::u8string in C++20
    auto S2 =  L"hello"s; // std::wstring
    auto S3 =  u"hello"s; // std::u16string
    auto S4 =  U"hello"s; // std::u32string

    // Combining raw string literals with standard s-suffix
    auto S5 =   R"("Hello \ world")"s; // std::string from a raw const char*
    auto S6 = u8R"("Hello \ world")"s; // std::string from a raw const char* before C++20, encoded as UTF-8,
                                       // std::u8string in C++20
    auto S7 =  LR"("Hello \ world")"s; // std::wstring from a raw const wchar_t*
    auto S8 =  uR"("Hello \ world")"s; // std::u16string from a raw const char16_t*, encoded as UTF-16
    auto S9 =  UR"("Hello \ world")"s; // std::u32string from a raw const char32_t*, encoded as UTF-32
}

Zeichenfolgenliterale können keine Präfixe oder u8Präfixe LuU aufweisen, um schmales Zeichen (Single-Byte- oder Multi-Byte-Zeichen), UTF-8, Wide Character (UCS-2 oder UTF-16), UTF-16- bzw. UTF-32-Codierungen zu kennzeichnen. Ein unformatiertes Zeichenfolgenliteral kann für URuRLRu8Rdie unformatierten Versionsäquivalente dieser Codierungen Äquivalente aufweisen.R Zum Erstellen temporärer oder statischer Werte können Sie Zeichenfolgenliterale oder unformatierte std::string Zeichenfolgenliterale mit einem s Suffix verwenden. Weitere Informationen finden Sie im Abschnitt "Zeichenfolgenliterale " weiter unten. Weitere Informationen zum grundlegenden Quellzeichensatz, universellen Zeichennamen und zum Verwenden von Zeichen aus erweiterten Codeseiten in Ihrem Quellcode finden Sie unter "Zeichensätze".

Zeichenliterale

Ein Zeichenfolgenliteral besteht aus einem konstanten Zeichen. Es wird durch das Zeichen dargestellt, das von einfachen Anführungszeichen umgeben ist. Es gibt fünf Arten von Zeichenliteralen:

  • Normale Zeichenliterale vom Typ char, z. B. 'a'

  • UTF-8-Zeichenliterale vom Typ char (char8_t in C++20), z. B. u8'a'

  • Breite Zeichenliterale vom Typ wchar_t, beispielsweise L'a'

  • UTF-16-Zeichenliterale vom Typ char16_t, z. B. u'a'

  • UTF-32-Zeichenliterale vom Typ char32_t, z. B. U'a'

Das zeichen, das für ein Zeichenliteral verwendet wird, kann ein beliebiges Zeichen sein, mit Ausnahme der reservierten Zeichen umgekehrter Schrägstrich (\), eines einfachen Anführungszeichens (') oder einer Neuen Zeile. Reservierte Zeichen können mit einer Escapesequenz angegeben werden. Zeichen können mit universellen Zeichennamen angegeben werden, solange der Typ groß genug ist, das Zeichen zu enthalten.

Codieren

Zeichenliterale werden je nach Präfix unterschiedlich codiert.

  • Ein Zeichenliteral ohne Präfix ist ein normales Zeichenliteral. Der Wert eines gewöhnlichen Zeichenliterals, das ein einzelnes Zeichen, eine Escapesequenz oder einen universellen Zeichennamen enthält, der im Ausführungszeichensatz dargestellt werden kann, weist einen Wert auf, der dem numerischen Wert seiner Codierung im Ausführungszeichensatz entspricht. Ein gewöhnliches Zeichenliteral, das mehr als ein Zeichen, eine Escapesequenz oder einen universellen Zeichennamen enthält, ist ein Mehrzeichenliteral. Ein multicharacter Literal oder ein normales Zeichenliteral, das nicht im Ausführungszeichensatz dargestellt werden kann, hat Typ int, und sein Wert ist implementierungsdefiniert. MsVC finden Sie unten im Microsoft-spezifischen Abschnitt.

  • Ein Zeichenliteral, das mit dem L Präfix beginnt, ist ein Breitzeichenliteral. Der Wert eines Breitzeichenliterals, das ein einzelnes Zeichen, eine Escapesequenz oder einen universellen Zeichennamen enthält, weist einen Wert auf, der dem numerischen Wert seiner Codierung im Breite-Zeichen-Satz der Ausführung entspricht, es sei denn, das Zeichenliteral weist keine Darstellung im Ausführungsweitenzeichensatz auf, in diesem Fall ist der Wert implementierungsdefiniert. Der Wert eines Breitzeichenliterals, das mehrere Zeichen, Escapesequenzen oder universelle Zeichennamen enthält, ist implementierungsdefiniert. MsVC finden Sie unten im Microsoft-spezifischen Abschnitt.

  • Ein Zeichenliteral, das mit dem u8 Präfix beginnt, ist ein UTF-8-Zeichenliteral. Der Wert eines UTF-8-Zeichenliterals, das ein einzelnes Zeichen, eine Escapesequenz oder einen universellen Zeichennamen enthält, weist einen Wert auf, der dem ISO 10646-Codepunktwert entspricht, wenn es durch eine einzelne UTF-8-Codeeinheit dargestellt werden kann (entsprechend dem C0 Controls and Basic Latin Unicode Block). Wenn der Wert nicht durch eine einzelne UTF-8-Codeeinheit dargestellt werden kann, ist das Programm unformiert. Ein UTF-8-Zeichenliteral, das mehr als ein Zeichen, eine Escapesequenz oder einen universellen Zeichennamen enthält, ist unformiert.

  • Ein Zeichenliteral, das mit dem u Präfix beginnt, ist ein UTF-16-Zeichenliteral. Der Wert eines UTF-16-Zeichenliterals, das ein einzelnes Zeichen, eine Escapesequenz oder einen universellen Zeichennamen enthält, weist einen Wert auf, der dem ISO 10646-Codepunktwert entspricht, wenn er durch eine einzelne UTF-16-Codeeinheit dargestellt werden kann (entsprechend der einfachen mehrsprachigen Ebene). Wenn der Wert nicht durch eine einzelne UTF-16-Codeeinheit dargestellt werden kann, ist das Programm unformatiert. Ein UTF-16-Zeichenliteral, das mehr als ein Zeichen, eine Escapesequenz oder einen universellen Zeichennamen enthält, ist unformiert.

  • Ein Zeichenliteral, das mit dem U Präfix beginnt, ist ein UTF-32-Zeichenliteral. Der Wert eines UTF-32-Zeichenliterals, das ein einzelnes Zeichen, eine Escapesequenz oder einen universellen Zeichennamen enthält, weist einen Wert auf, der dem ISO 10646-Codepunktwert entspricht. Ein UTF-32-Zeichenliteral, das mehr als ein Zeichen, eine Escapesequenz oder einen universellen Zeichennamen enthält, ist unformiert.

Escapesequenzen

Es gibt drei Arten von Escapesequenzen: einfache, oktale und hexadezimale. Escapesequenzen können eine der folgenden Werte sein:

Wert Escapesequenz
Zeilenumbruch \n
umgekehrter Schrägstrich \\
Horizontaler Tabulator \t
Fragezeichen ? Oder\?
Vertikaler Tabulator \v
einfache Anführungszeichen \'
Rücktaste \b
Doppeltes Anführungszeichen \"
Wagenrücklauf \r
das Nullzeichen \0
Seitenvorschub \f
Oktal \ooo
Warnung (Glocke) \a
Hexadezimal \xhhh

Eine oktale Escapesequenz ist ein umgekehrter Schrägstrich gefolgt von einer Sequenz von 1 bis drei oktalen Ziffern. Eine oktale Escapesequenz wird am ersten Zeichen beendet, bei dem es sich nicht um eine oktale Ziffer handelt, wenn sie früher als die dritte Ziffer gefunden wird. Der höchste mögliche oktale Wert ist \377.

Eine hexadezimale Escapesequenz ist ein umgekehrter Schrägstrich gefolgt vom Zeichen x, gefolgt von einer Abfolge einer oder mehrerer Hexadezimalziffern. Führende Nullen werden ignoriert. In einem gewöhnlichen oder u8-präfixierten Zeichenliteral ist der höchste Hexadezimalwert 0xFF. In einem Breitzeichenliteral mit dem Präfix L oder u ist 0xFFFF der höchste Hexadezimalwert. In einem Breitzeichenliteral mit dem Präfix U ist 0xFFFFFFFF der höchste Hexadezimalwert.

Dieser Beispielcode zeigt einige Beispiele für Escapezeichen mit normalen Zeichenliteralen. Die gleiche Escapesequenzsyntax ist für die anderen Zeichenliteraltypen gültig.

#include <iostream>
using namespace std;

int main() {
    char newline = '\n';
    char tab = '\t';
    char backspace = '\b';
    char backslash = '\\';
    char nullChar = '\0';

    cout << "Newline character: " << newline << "ending" << endl;
    cout << "Tab character: " << tab << "ending" << endl;
    cout << "Backspace character: " << backspace << "ending" << endl;
    cout << "Backslash character: " << backslash << "ending" << endl;
    cout << "Null character: " << nullChar << "ending" << endl;
}
/* Output:
Newline character:
ending
Tab character:  ending
Backspace character:ending
Backslash character: \ending
Null character:  ending
*/

Das umgekehrte Schrägstrichzeichen (\) ist ein Zeilenfortsetzungszeichen, wenn es am Ende einer Zeile platziert wird. Wenn ein umgekehrter Schrägstrich als Zeichenliteral angezeigt werden soll, müssen Sie zwei umgekehrte Schrägstriche in einer Zeile (\\) eingeben. Weitere Informationen zum Zeilenfortsetzungszeichen finden Sie unter Phases of Translation.

Microsoft-spezifisch

Um einen Wert aus einem schmalen Multicharacterliteral zu erstellen, konvertiert der Compiler das Zeichen oder die Zeichensequenz zwischen einzelnen Anführungszeichen in 8-Bit-Werte innerhalb einer 32-Bit-Ganzzahl. Mehrere Zeichen im Literal belegen entsprechende Bytes nach Bedarf vom höherwertigen zum niederwertigen Byte. Der Compiler konvertiert dann die ganze Zahl nach den üblichen Regeln in den Zieltyp. Um beispielsweise einen char Wert zu erstellen, verwendet der Compiler das Byte mit niedriger Reihenfolge. Um einen wchar_t - oder einen char16_t -Wert zu erstellen, nimmt der Compiler das niederwertige Wort. Der Compiler warnt, dass das Ergebnis abgeschnitten wird, wenn irgendwelche Bits über dem zugewiesenen Byte oder Word Bits festgelegt sind.

char c0    = 'abcd';    // C4305, C4309, truncates to 'd'
wchar_t w0 = 'abcd';    // C4305, C4309, truncates to '\x6364'
int i0     = 'abcd';    // 0x61626364

Eine oktale Escapesequenz, die scheinbar mehr als drei Ziffern enthält, wird als 3-stellige Oktalsequenz behandelt, gefolgt von den nachfolgenden Ziffern als Zeichen in einem Mehrzeichenliteral, was überraschende Ergebnisse ergeben kann. Beispiel:

char c1 = '\100';   // '@'
char c2 = '\1000';  // C4305, C4309, truncates to '0'

Escapesequenzen, die scheinbar nicht oktale Zeichen enthalten, werden als oktale Abfolge bis zum letzten oktalen Zeichen ausgewertet, gefolgt von den zeichen re Standard als nachfolgende Zeichen in einem Mehrzeichenliteral. Warnung C4125 wird generiert, wenn das erste nicht oktale Zeichen eine Dezimalziffer ist. Beispiel:

char c3 = '\009';   // '9'
char c4 = '\089';   // C4305, C4309, truncates to '9'
char c5 = '\qrs';   // C4129, C4305, C4309, truncates to 's'

Eine oktale Escapesequenz, die einen höheren Wert aufweist als \377 fehler C2022: "wert-in-dezimal": zu groß für Zeichen.

Eine Escapesequenz, die scheinbar hexadezimale und nicht hexadezimale Zeichen enthält, wird als mehrcharacter Literal ausgewertet, das eine hexadezimale Escapesequenz bis zum letzten hexadezimalen Zeichen enthält, gefolgt von den nicht hexadezimalen Zeichen. Eine hexadezimale Escapesequenz, die keine hexadezimalen Ziffern enthält, verursacht den Compilerfehler C2153: "Hexadezimalliterale müssen mindestens eine Hexadezimalziffer aufweisen".

char c6 = '\x0050'; // 'P'
char c7 = '\x0pqr'; // C4305, C4309, truncates to 'r'

Wenn ein breites Zeichenliteral mit einem Präfix L eine Multicharactersequenz enthält, wird der Wert aus dem ersten Zeichen entnommen, und der Compiler löst die Warnung C4066 aus. Nachfolgende Zeichen werden ignoriert, im Gegensatz zum Verhalten des entsprechenden normalen Multicharacterliterals.

wchar_t w1 = L'\100';   // L'@'
wchar_t w2 = L'\1000';  // C4066 L'@', 0 ignored
wchar_t w3 = L'\009';   // C4066 L'\0', 9 ignored
wchar_t w4 = L'\089';   // C4066 L'\0', 89 ignored
wchar_t w5 = L'\qrs';   // C4129, C4066 L'q' escape, rs ignored
wchar_t w6 = L'\x0050'; // L'P'
wchar_t w7 = L'\x0pqr'; // C4066 L'\0', pqr ignored

Der microsoftspezifische Abschnitt endet hier.

Universelle Zeichennamen

In Zeichenliteralen und systemeigenen (nicht unformatierten) Zeichenfolgenliteralen kann jedes Zeichen durch einen universellen Zeichennamen dargestellt werden. Universelle Zeichennamen werden durch ein Präfix \U gebildet, gefolgt von einem achtstelligen Unicode-Codepunkt oder durch ein Präfix \u gefolgt von einem vierstelligen Unicode-Codepunkt. Alle acht bzw. vier Ziffern müssen vorhanden sein, damit sich ein wohlgeformter universeller Zeichenname ergibt.

char u1 = 'A';          // 'A'
char u2 = '\101';       // octal, 'A'
char u3 = '\x41';       // hexadecimal, 'A'
char u4 = '\u0041';     // \u UCN 'A'
char u5 = '\U00000041'; // \U UCN 'A'

Ersatzzeichenpaare

Universelle Zeichennamen können werte im Ersatzcodepunktbereich D800-DFFF nicht codieren. Für Unicode-Ersatzzeichenpaare geben Sie den universellen Zeichennamen an, indem Sie \UNNNNNNNNverwenden, wobei NNNNNNNN ein achtstellige Codepunkt für das Zeichen ist. Der Compiler generiert bei Bedarf ein Ersatzpaar.

In C++03 erlaubte die Sprache nur, dass eine Teilmenge von Zeichen durch ihre universellen Zeichennamen dargestellt wird und einige universelle Zeichennamen zulässig sind, die tatsächlich keine gültigen Unicode-Zeichen darstellen. Dieser Fehler wurde im C++11-Standard behoben. In C++11 können sowohl für Zeichen- und Zeichenfolgenliterale als auch für Bezeichner universelle Zeichennamen verwendet werden. Weitere Informationen zu universellen Zeichennamen finden Sie unter Character Sets. Weitere Informationen zu Unicode finden Sie unter Unicode. Weitere Informationen zu Ersatzzeichenpaaren finden Sie im Artikel über Ersatzzeichenpaare und zusätzliche Zeichen.

Zeichenfolgenliterale

Ein Zeichenfolgenliteral stellt eine Folge von Zeichen dar, die zusammen eine auf NULL endende Zeichenfolge bilden. Die Zeichen müssen zwischen doppelten Anführungszeichen eingeschlossen werden. Es gibt die folgenden Arten von Zeichenfolgenliteralen:

Schmale Zeichenfolgenliterale

Ein schmales Zeichenfolgenliteral ist ein nicht präfixiertes, durch doppeltes Anführungszeichen getrenntes Array vom Typ const char[n]Null, wobei n die Länge des Arrays in Byte ist. Ein Schmalzeichenfolgenliteral kann jedes Grafikzeichen außer einem doppelten Anführungszeichen ("), umgekehrten Schrägstrichen (\) oder Zeilenumbruchzeichen enthalten. Ein Schmalzeichenfolgenliteral kann auch die oben aufgelisteten Escapesequenzen sowie universelle Zeichennamen enthalten, die in ein Byte passen.

const char *narrow = "abcd";

// represents the string: yes\no
const char *escaped = "yes\\no";

UTF-8 codierte Zeichenfolgen

Eine UTF-8-codierte Zeichenfolge ist eine u8-präfixierte, durch Doppelte Anführungszeichen getrenntes, null-beendetes Array vom Typ const char[n], wobei n die Länge des codierten Arrays in Byte ist. Ein mit dem Präfix u8 versehenes Zeichenfolgenliteral kann jedes Grafikzeichen außer einem doppelten Anführungszeichen ("), umgekehrten Schrägstrichen (\) oder Zeilenumbruchzeichen enthalten. Ein mit dem Präfix u8 versehenes Zeichenfolgenliteral kann auch die Escapesequenzen, die oben aufgelistet sind, sowie jeden universellen Zeichennamen enthalten.

C++20 führt den portablen char8_t Zeichentyp (UTF-8-codiertes 8-Bit-Unicode) ein. In C++20 u8 geben Literalpräfixe Zeichen oder Zeichenfolgen anstelle von char8_tchar.

// Before C++20
const char* str1 = u8"Hello World";
const char* str2 = u8"\U0001F607 is O:-)";
// C++20 and later
const char8_t* u8str1 = u8"Hello World";
const char8_t* u8str2 = u8"\U0001F607 is O:-)";

Breite Zeichenfolgenliterale

Ein breites Zeichenfolgenliteral ist ein durch Null beendetes Array mit Konstanten wchar_t , das mit dem Präfix 'L' versehen ist und ein beliebiges Grafikzeichen enthält, mit Ausnahme des doppelten Anführungszeichens ("), des umgekehrten Schrägstrichs (\) oder des Zeilenumbruchs. Ein Breitzeichenfolgenliteral kann die Escapesequenzen, die oben aufgelistet sind, sowie jeden universellen Zeichennamen enthalten.

const wchar_t* wide = L"zyxw";
const wchar_t* newline = L"hello\ngoodbye";

char16_t und char32_t (C ++ 11)

C ++ 11 stellt die portablen char16_t (16-Bit-Unicode) und char32_t (32-Bit-Unicode)-Zeichentypen vor:

auto s3 = u"hello"; // const char16_t*
auto s4 = U"hello"; // const char32_t*

Unformatierte Zeichenfolgenliterale (C++11)

Ein unformatiertes Zeichenfolgenliteral ist ein null-gekündigtes Array ( eines beliebigen Zeichentyps), das ein beliebiges Grafikzeichen enthält, einschließlich des doppelten Anführungszeichens ("), des umgekehrten Schrägstrichs (\) oder des Zeilenumbruchs. Unformatierte Zeichenfolgenliterale werden häufig in regulären Ausdrücken, die Zeichenklassen verwenden, und in HTML-Zeichenfolgen und XML-Zeichenfolgen verwendet. Beispiele finden Sie im folgenden Artikel: Bjarne Stroustrups FAQ zu C++11.

// represents the string: An unescaped \ character
const char* raw_narrow = R"(An unescaped \ character)";
const wchar_t*  raw_wide  = LR"(An unescaped \ character)";
const char*     raw_utf8a = u8R"(An unescaped \ character)"; // Before C++20
const char8_t*  raw_utf8b = u8R"(An unescaped \ character)"; // C++20
const char16_t* raw_utf16 = uR"(An unescaped \ character)";
const char32_t* raw_utf32 = UR"(An unescaped \ character)";

Ein Trennzeichen ist eine benutzerdefinierte Sequenz von bis zu 16 Zeichen, die unmittelbar vor der öffnenden Klammer eines unformatierten Zeichenfolgenliterals stehen und unmittelbar der schließenden Klammer folgen. Beispielsweise ist in R"abc(Hello"\()abc" die Zeichenfolge abc die Trennzeichensequenz und Hello"\(der Zeichenfolgeninhalt. Sie können ein Trennzeichen verwenden, um unformatierte Zeichenfolgen eindeutig zu machen, die doppelte Anführungszeichen und Klammern enthalten. Dieses Zeichenfolgenliteral verursacht einen Compilerfehler:

// meant to represent the string: )"
const char* bad_parens = R"()")";  // error C2059

Durch ein Trennzeichen wird er jedoch behoben:

const char* good_parens = R"xyz()")xyz";

Sie können ein unformatiertes Zeichenfolgenliteral erstellen, das eine neue Zeile (nicht das Escapezeichen) in der Quelle enthält:

// represents the string: hello
//goodbye
const wchar_t* newline = LR"(hello
goodbye)";

std::string literals (C++14)

std::string Literale sind Standardbibliotheksimplementierungen von benutzerdefinierten Literalen (siehe unten), die als "xyz"s (mit einem s Suffix) dargestellt werden. Diese Art von Zeichenfolgenliteral erzeugt ein temporäres Objekt vom Typ std::string, , std::wstring, std::u32stringoder std::u16string, abhängig vom angegebenen Präfix. Wenn wie oben kein Präfix verwendet wird, wird ein std::string Präfix erstellt. L"xyz"s erzeugt ein std::wstring. u"xyz"s erzeugt eine std::u16string und U"xyz"s erzeugt eine std::u32string.

//#include <string>
//using namespace std::string_literals;
string str{ "hello"s };
string str2{ u8"Hello World" };     // Before C++20
u8string u8str2{ u8"Hello World" }; // C++20
wstring str3{ L"hello"s };
u16string str4{ u"hello"s };
u32string str5{ U"hello"s };

Das s Suffix kann auch für unformatierte Zeichenfolgenliterale verwendet werden:

u32string str6{ UR"(She said "hello.")"s };

std::string Literale werden im Namespace std::literals::string_literals in der <Zeichenfolgenheaderdatei> definiert. Da std::literals::string_literalsund std::literals beide als inlinenamespacesdeklariert werden, wird std::literals::string_literals automatisch so behandelt, als ob sie direkt zum Namespace stdgehören.

Größe von Zeichenfolgenliteralen

Bei ANSI-Zeichenfolgen char* und anderen Single-Byte-Codierungen (aber nicht UTF-8) ist die Größe (in Bytes) eines Zeichenfolgenliterals die Anzahl der Zeichen plus 1 für das endende Nullzeichen. Bei allen anderen Zeichenfolgentypen bezieht sich die Größe nicht ausschließlich auf die Anzahl der Zeichen. UTF-8 verwendet bis zu vier char Elemente zum Codieren einiger Codeeinheiten und char16_t oder wchar_t codiert als UTF-16 können zwei Elemente (für insgesamt vier Byte) verwenden, um eine einzelne Codeeinheit zu codieren. In diesem Beispiel wird die Größe eines Breitzeichenfolgenliterals in Bytes gezeigt:

const wchar_t* str = L"Hello!";
const size_t byteSize = (wcslen(str) + 1) * sizeof(wchar_t);

Beachten Sie, dass strlen() und wcslen() nicht die Größe des endenden Nullzeichens enthalten ist, deren Größe der Elementgröße des Zeichenfolgentyps entspricht: ein Byte in einem oder char8_t* einer char* Zeichenfolge, zwei Bytes einwchar_t*- oder char16_t* Zeichenfolgen und vier Bytes für char32_t* Zeichenfolgen.

In Versionen von Visual Studio vor Visual Studio 2022, Version 17.0, beträgt die maximale Länge eines Zeichenfolgenliterals 65.535 Bytes. Diese Begrenzung gilt sowohl für schmale Zeichenfolgenliterale als auch für breite Zeichenfolgenliterale. In Visual Studio 2022, Version 17.0 und höher, wird diese Einschränkung aufgehoben, und die Länge der Zeichenfolge wird durch verfügbare Ressourcen begrenzt.

Ändern von Zeichenfolgenliteralen

Da Zeichenfolgenliterale (nicht einschließlich std::string Literale) Konstanten sind, verursacht der Versuch, sie ( z. B. ) zu ändern, str[2] = 'A'einen Compilerfehler.

Microsoft-spezifisch

In Microsoft C++ können Sie ein Zeichenfolgenliteral verwenden, um einen Zeiger auf nicht-const char oder wchar_tzu initialisieren. Diese Nichtkonstinitialisierung ist in C99-Code zulässig, ist jedoch in C++98 veraltet und in C++11 entfernt. Ein Versuch, die Zeichenfolge zu ändern, verursacht eine Zugriffsverletzung, wie in diesem Beispiel:

wchar_t* str = L"hello";
str[2] = L'a'; // run-time error: access violation

Sie können dazu führen, dass der Compiler einen Fehler ausgibt, wenn ein Zeichenfolgenliteral in einen Nicht-Const-Zeichenzeiger konvertiert wird, wenn Sie die /Zc:strictStrings Compileroption (Zeichenfolgenliteraltypkonvertierung deaktivieren) festlegen. Wir empfehlen dies für standardkonformen portablen Code. Außerdem empfiehlt es sich, die auto Schlüsselwort (keyword) zum Deklarieren von Zeichenfolgenliteralinitialisierten Zeigern zu verwenden, da sie in den richtigen (Const)-Typ aufgelöst wird. In diesem Codebeispiel wird ein Versuch abgefangen, zur Kompilierungszeit in ein Zeichenfolgenliteral zu schreiben:

auto str = L"hello";
str[2] = L'a'; // C3892: you cannot assign to a variable that is const.

In einigen Fällen können identische Zeichenfolgenliterale "zusammengelegt" werden, um Speicherplatz in der ausführbaren Datei zu sparen. Im Zeichenfolgenliteral-Pooling bewirkt der Compiler, dass alle Verweise auf ein bestimmtes Zeichenfolgenliteral auf die gleiche Position im Arbeitsspeicher zeigen, anstatt dass alle Verweise auf eine separate Instanz des Zeichenfolgenliterals zeigen. Verwenden Sie die Compileroption, um die /GF Zeichenfolgenpooling zu aktivieren.

Der microsoftspezifische Abschnitt endet hier.

Verketten von benachbarten Zeichenfolgenliteralen

Benachbarte breite oder schmale Zeichenfolgenliterale werden verkettet. Diese Deklaration ist:

char str[] = "12" "34";

mit dieser Deklaration identisch:

char atr[] = "1234";

und mit dieser Deklaration identisch:

char atr[] =  "12\
34";

Durch die Verwendung eingebetteter hexadezimaler Escapesequenzen für die Angabe von Zeichenfolgenliterale können unerwartete Ergebnisse verursacht werden. Im folgenden Beispiel soll ein Zeichenfolgenliteral erstellt werden, das ASCII 5-Zeichen enthält, gefolgt von den Zeichen f, i, v und e:

"\x05five"

Das eigentliche Ergebnis ist ein hexadezimales 5F, also der ASCII-Code für einen Unterstrich, gefolgt von den Zeichen i, v und e. Um das richtige Ergebnis zu erhalten, können Sie eine der folgenden Escapesequenzen verwenden:

"\005five"     // Use octal literal.
"\x05" "five"  // Use string splicing.

std::string Literale (und die zugehörigen std::u8string, std::u16stringund std::u32string) können mit dem Operator verkettet werden, der + für basic_string Typen definiert ist. Sie können auch auf die gleiche Weise wie benachbarte Zeichenfolgenliterale verkettet werden. In beiden Fällen müssen die Zeichenfolgencodierung und das Suffix übereinstimmen:

auto x1 = "hello" " " " world"; // OK
auto x2 = U"hello" " " L"world"; // C2308: disagree on prefix
auto x3 = u8"hello" " "s u8"world"z; // C3688, disagree on suffixes

Zeichenfolgenliterale mit universellen Zeichennamen

In systemeigenen (nicht unformatierten) Zeichenfolgenliteralen können universelle Zeichennamen verwendet werden, um jedes beliebige Zeichen darzustellen, solange der jeweilige universelle Zeichenname als ein oder mehrere Zeichen im string-Datentyp codiert werden kann. Beispielsweise kann ein universeller Zeichenname, der ein erweitertes Zeichen darstellt, nicht in einer schmalen Zeichenfolge mithilfe der ANSI-Codeseite codiert werden, kann aber in schmalen Zeichenfolgen in einigen Multibyte-Codeseiten oder in UTF-8-Zeichenfolgen oder in einer breiten Zeichenfolge codiert werden. In C++11 wird die Unicode-Unterstützung durch die char16_t* Typen und char32_t* Zeichenfolgen erweitert, und C++20 erweitert sie auf den char8_t Typ:

// ASCII smiling face
const char*     s1 = ":-)";

// UTF-16 (on Windows) encoded WINKING FACE (U+1F609)
const wchar_t*  s2 = L"😉 = \U0001F609 is ;-)";

// UTF-8  encoded SMILING FACE WITH HALO (U+1F607)
const char*     s3a = u8"😇 = \U0001F607 is O:-)"; // Before C++20
const char8_t*  s3b = u8"😇 = \U0001F607 is O:-)"; // C++20

// UTF-16 encoded SMILING FACE WITH OPEN MOUTH (U+1F603)
const char16_t* s4 = u"😃 = \U0001F603 is :-D";

// UTF-32 encoded SMILING FACE WITH SUNGLASSES (U+1F60E)
const char32_t* s5 = U"😎 = \U0001F60E is B-)";

Siehe auch

Zeichensätze
Numerische, boolesche und Zeigerliterale
Benutzerdefinierte Literale