Namensräume
Varianten
Aktionen

Zeichenkettenliteral

Von cppreference.com
< cpp‎ | Sprache
 
 
C++ Sprache
Allgemeine Themen
Kontrollfluss
Bedingte Ausführungsaussagen
if
Iterationsanweisungen (Schleifen)
for
Bereichs-for (C++11)
Sprunganweisungen
Funktionen
Funktionsdeklaration
Lambda-Funktionsausdruck
inline-Spezifizierer
Dynamische Ausnahmespezifikationen (bis C++17*)
noexcept-Spezifizierer (C++11)
Ausnahmen
Namensräume
Typen
Spezifizierer
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Speicherdauer-Spezifizierer
Initialisierung
Ausdrücke
Alternative Darstellungen
Literale
Boolesch - Ganzzahl - Gleitkommazahl
Zeichen - Zeichenkette - nullptr (C++11)
Benutzerdefinierte (C++11)
Dienstprogramme
Attribute (C++11)
Typen
typedef-Deklaration
Typalias-Deklaration (C++11)
Umwandlungen
Speicherzuweisung
Klassen
Klassenspezifische Funktionseigenschaften
explicit (C++11)
static

Spezielle Member-Funktionen
Templates
Sonstiges
 
 

Inhalt

[bearbeiten] Syntax

"s-char-seq (optional)" (1)
R"d-char-seq (optional)(r-char-seq (optional))d-char-seq (optional)" (2) (seit C++11)
L"s-char-seq (optional)" (3)
LR"d-char-seq (optional)(r-char-seq (optional))d-char-seq (optional)" (4) (seit C++11)
u8"s-char-seq (optional)" (5) (seit C++11)
u8R"d-char-seq (optional)(r-char-seq (optional))d-char-seq (optional)" (6) (seit C++11)
u"s-char-seq (optional)" (7) (seit C++11)
uR"d-char-seq (optional)(r-char-seq (optional))d-char-seq (optional)" (8) (seit C++11)
U"s-char-seq (optional)" (9) (seit C++11)
UR"d-char-seq (optional)(r-char-seq (optional))d-char-seq (optional)" (10) (seit C++11)

[bearbeiten] Erklärung

s-char-seq - Eine Folge von einem oder mehreren s-char s
s-char - Einer von
basic-s-char - Ein Zeichen aus dem Übersetzungszeichensatz, außer dem doppelten Anführungszeichen ", dem umgekehrten Schrägstrich \ oder dem Zeilenumbruchzeichen
d-char-seq - Eine Folge von einem oder mehreren d-char s, höchstens 16 Zeichen lang
d-char - Ein Zeichen aus dem Grundzeichensatz, außer Klammern, umgekehrtem Schrägstrich und Leerzeichen
r-char-seq - Eine Folge von einem oder mehreren r-char s, mit der Ausnahme, dass sie nicht die schließende Sequenz )d-char-seq" enthalten darf
r-char - Ein Zeichen aus dem Übersetzungszeichensatz

 Syntax  Art Typ Kodierung
(1,2)  gewöhnliches Zeichenkettenliteral  const char[N] gewöhnliche Literal-Kodierung
(3,4) breites Zeichenkettenliteral const wchar_t[N] breite Literal-Kodierung
(5,6) UTF-8-Zeichenkettenliteral

const char[N]

(bis C++20)

const char8_t[N]

(seit C++20)
UTF-8
(7,8) UTF-16-Zeichenkettenliteral const char16_t[N] UTF-16
(9,10) UTF-32-Zeichenkettenliteral const char32_t[N] UTF-32

In den obigen Typen ist N die Anzahl der kodierten Code Units, die weiter unten bestimmt wird.

Gewöhnliche und UTF-8(seit C++11)-Zeichenkettenliterale werden gemeinsam als schmale Zeichenkettenliterale bezeichnet.

Die Auswertung eines Zeichenkettenliterals ergibt ein Zeichenkettenliteral-Objekt mit statischer Speicherdauer. Ob alle Zeichenkettenliterale in nicht überlappenden Objekten gespeichert werden und ob aufeinanderfolgende Auswertungen eines Zeichenkettenliterals dasselbe oder ein anderes Objekt ergeben, ist nicht spezifiziert.

Der Versuch, ein Zeichenkettenliteral-Objekt zu modifizieren, führt zu undefiniertem Verhalten.

bool b = "bar" == 3 + "foobar"; // can be true or false, unspecified
 
const char* pc = "Hello";
char* p = const_cast<char*>(pc);
p[0] = 'M'; // undefined behavior

Raw-Zeichenkettenliterale

Raw-Zeichenkettenliterale sind Zeichenkettenliterale mit einem Präfix, der R enthält (Syntaxen (2,4,6,8,10)). Sie maskieren kein Zeichen, was bedeutet, dass alles zwischen den Begrenzern d-char-seq ( und )d-char-seq Teil der Zeichenkette wird. Die abschließende d-char-seq ist dieselbe Zeichenfolge wie die anfängliche d-char-seq.

// OK: contains one backslash,
// equivalent to "\\"
R"(\)";
 
// OK: contains four \n pairs,
// equivalent to "\\n\\n\\n\\n"
R"(\n\n\n\n)";
 
// OK: contains one close-parenthesis, two double-quotes and one open-parenthesis,
// equivalent to ")\"\"("
R"-()""()-";
 
// OK: equivalent to "\n)\\\na\"\"\n"
R"a(
)\
a""
)a";
 
// OK: equivalent to "x = \"\"\\y\"\""
R"(x = ""\y"")";
 
// R"<<(-_-)>>"; // Error: begin and end delimiters do not match
// R"-()-"-()-"; // Error: )-" appears in the middle and terminates the literal
(seit C++11)

[bearbeiten] Initialisierung

Zeichenkettenliteral-Objekte werden mit der Code-Unit-Sequenz initialisiert, die den Code-Unit-Werten der s-char -Sequenz und r-char s(seit C++11) des Zeichenkettenliterals entspricht, zuzüglich eines abschließenden Nullzeichens (U+0000), in der folgenden Reihenfolge:

1) Für jede zusammenhängende Folge von basic-s-char s, r-char s,(seit C++11) einfache Escape-Sequenzen und universelle Zeichennamen wird die von ihnen bezeichnete Zeichensequenz mithilfe der zugehörigen Zeichenkodierung des Zeichenkettenliterals in eine Code-Unit-Sequenz kodiert. Wenn einem Zeichen keine Darstellung in der zugehörigen Zeichenkodierung fehlt, ist das Programm ill-formed.
Wenn die zugehörige Zeichenkodierung zustandsbehaftet ist, wird die erste solche Sequenz beginnend mit dem initialen Kodierungszustand kodiert und jede nachfolgende Sequenz beginnend mit dem finalen Kodierungszustand der vorherigen Sequenz.
2) Für jede numerische Escape-Sequenz, wobei v der Ganzzahlwert ist, der durch die Ziffernfolge im oktalen oder hexadezimalen Zahlenwert der Sequenz dargestellt wird, und T der Elementtyp des Arrays des Zeichenkettenliterals ist (siehe Tabelle oben)
  • Wenn v den Bereich der darstellbaren Werte von T nicht überschreitet, trägt die Escape-Sequenz eine einzelne Code Unit mit dem Wert v.
  • Andernfalls, wenn das Zeichenkettenliteral die Syntax (1) oder (3) hat, und(seit C++11) v den Bereich der darstellbaren Werte des entsprechenden vorzeichenlosen Typs für den zugrundeliegenden Typ von T nicht überschreitet, dann trägt die Escape-Sequenz eine einzelne Code Unit mit einem eindeutigen Wert vom Typ T, der kongruent zu v mod 2S
    ist, wobei S die Breite von T ist.
  • Andernfalls ist das Programm fehlerhaft.
Wenn die zugehörige Zeichenkodierung zustandsbehaftet ist, haben alle solchen Sequenzen keine Auswirkung auf den Kodierungszustand.
3) Jede bedingte Escape-Sequenz trägt eine implementierungsdefinierte Code-Unit-Sequenz.
Wenn die zugehörige Zeichenkodierung zustandsbehaftet ist, ist es implementierungsdefiniert, welche Auswirkungen diese Sequenzen auf den Kodierungszustand haben.

[bearbeiten] Konkatenation

Nebeneinanderliegende Zeichenkettenliterale werden in Übersetzungsphase 6 (nach der Präprozessierung) konkateniert.

  • Wenn die beiden Zeichenkettenliterale vom selben Typ sind, ist das konkatenierte Zeichenkettenliteral ebenfalls von diesem Typ.
  • Wenn ein gewöhnliches Zeichenkettenliteral neben einem breiten Zeichenkettenliteral liegt, ist das Verhalten undefiniert.
(bis C++11)
  • Wenn ein gewöhnliches Zeichenkettenliteral neben einem nicht-gewöhnlichen Zeichenkettenliteral liegt, ist das konkatenierte Zeichenkettenliteral vom Typ des letzteren.
  • Wenn ein UTF-8-Zeichenkettenliteral neben einem breiten Zeichenkettenliteral liegt, ist das Programm ill-formed.
  • Jede andere Kombination ist bedingt unterstützt mit implementierungsdefinierten Semantiken.[1]
(bis C++23)
  • Jede andere Kombination ist ill-formed.
(seit C++23)
(seit C++11)
"Hello, " "world!" // at phase 6, the 2 string literals form "Hello, world!"
 
L"Δx = %" PRId16   // at phase 4, PRId16 expands to "d"
                   // at phase 6, L"Δx = %" and "d" form L"Δx = %d"
  1. Keine bekannte Implementierung unterstützt eine solche Konkatenation.

[bearbeiten] Nicht ausgewertete Zeichenketten

Die folgenden Kontexte erwarten ein Zeichenkettenliteral, werten es aber nicht aus:

(seit C++11)
(seit C++14)
(seit C++20)
(seit C++26)


Es ist nicht spezifiziert, ob nicht-gewöhnliche Zeichenkettenliterale in diesen Kontexten erlaubt sind, mit der Ausnahme, dass ein Literaloperatorname ein gewöhnliches Zeichenkettenliteral verwenden muss(seit C++11).

(bis C++26)

Nur gewöhnliche Zeichenkettenliterale sind in diesen Kontexten erlaubt.

Jeder universelle Zeichenname und jede einfache Escape-Sequenz in einer nicht ausgewerteten Zeichenkette wird durch das Mitglied des Übersetzungszeichensatzes ersetzt, das sie bezeichnet. Eine nicht ausgewertete Zeichenkette, die eine numerische Escape-Sequenz oder eine bedingte Escape-Sequenz enthält, ist ill-formed.

(seit C++26)

[bearbeiten] Anmerkungen

Zeichenkettenliterale können zur Initialisierung von Zeichenarrays verwendet werden. Wenn ein Array wie char str[] = "foo"; initialisiert wird, enthält str eine Kopie der Zeichenkette "foo".

Zeichenkettenliterale sind in nicht-const char* oder wchar_t* konvertierbar und zuweisbar, um mit C kompatibel zu sein, wo Zeichenkettenliterale die Typen char[N] und wchar_t[N] haben. Eine solche implizite Konvertierung ist veraltet.

(bis C++11)

Zeichenkettenliterale sind nicht in nicht-const CharT* konvertierbar oder zuweisbar. Eine explizite Umwandlung (z. B. const_cast) muss verwendet werden, wenn eine solche Konvertierung gewünscht wird.

(seit C++11)

Ein Zeichenkettenliteral ist nicht notwendigerweise eine nullterminierte Zeichenfolge: Wenn ein Zeichenkettenliteral eingebettete Nullzeichen enthält, repräsentiert es ein Array, das mehr als eine Zeichenkette enthält.

const char* p = "abc\0def"; // std::strlen(p) == 3, but the array has size 8

Wenn eine gültige hexadezimale Ziffer einer hexadezimalen Escape-Sequenz in einem Zeichenkettenliteral folgt, schlägt die Kompilierung aufgrund einer ungültigen Escape-Sequenz fehl. Zeichenkettenkonkatenation kann als Workaround dienen.

//const char* p = "\xfff"; // error: hexadecimal escape sequence out of range
const char* p = "\xff""f"; // OK: the literal is const char[3] holding {'\xff','f','\0'}
Feature-Test-Makro Wert Std Feature
__cpp_char8_t 202207L (C++23)
(DR20)
Kompatibilität und Portabilität von char8_t (ermöglicht Initialisierung von (vorzeichenlosen) char-Arrays aus UTF-8-Zeichenkettenliteralen)
__cpp_raw_strings 200710L (C++11) Raw-Zeichenkettenliterale
__cpp_unicode_literals 200710L (C++11) Unicode-String-Literale

[bearbeiten] Beispiel

#include <iostream>
 
// array1 and array2 contains the same values:
char array1[] = "Foo" "bar";
char array2[] = {'F', 'o', 'o', 'b', 'a', 'r', '\0'};
 
const char* s1 = R"foo(
Hello
  World
)foo";
// same as
const char* s2 = "\nHello\n  World\n";
// same as
const char* s3 = "\n"
                 "Hello\n"
                 "  World\n";
 
const wchar_t* s4 = L"ABC" L"DEF"; // OK, same as
const wchar_t* s5 = L"ABCDEF";
const char32_t* s6 = U"GHI" "JKL"; // OK, same as
const char32_t* s7 = U"GHIJKL";
const char16_t* s9 = "MN" u"OP" "QR"; // OK, same as
const char16_t* sA = u"MNOPQR";
 
// const auto* sB = u"Mixed" U"Types";
        // before C++23 may or may not be supported by
        // the implementation; ill-formed since C++23
 
const wchar_t* sC = LR"--(STUV)--"; // OK, raw string literal
 
int main()
{
    std::cout << array1 << ' ' << array2 << '\n'
              << s1 << s2 << s3 << std::endl;
    std::wcout << s4 << ' ' << s5 << ' ' << sC
               << std::endl;
}

Ausgabe

Foobar Foobar
 
Hello
  World
 
Hello
  World
 
Hello
  World
 
ABCDEF ABCDEF STUV

[bearbeiten] Fehlerberichte

Die folgenden Verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.

DR angewendet auf Verhalten wie veröffentlicht Korrigiertes Verhalten
CWG 411
(P2029R4)
C++98 Escape-Sequenzen in Zeichenkettenliteralen konnten
nicht auf mehrere Code Units abgebildet werden
erlaubt
CWG 1656
(P2029R4)
C++98 die durch numerische Escape-Sequenzen bezeichneten Zeichen
in Zeichenkettenliteralen waren unklar
wurde klargestellt
CWG 1759 C++11 ein UTF-8-Zeichenkettenliteral konnte Code
Units enthalten, die in char nicht darstellbar sind
char kann alle UTF-8-Code-Units darstellen
CWG 1823 C++98 ob Zeichenkettenliterale unterschiedlich waren
war implementierungsdefiniert
Unterschiedlichkeit ist nicht spezifiziert, und dasselbe
Zeichenkettenliteral kann unterschiedliche Objekte ergeben
CWG 2333
(P2029R4)
C++11 es war unklar, ob numerische Escape-Sequenzen
in UTF-8/16/32-Zeichenkettenliteralen erlaubt waren
wurde klargestellt
CWG 2870 C++11 Das Konkatenationsergebnis zweier
gewöhnlicher Zeichenkettenliterale war unklar
wurde klargestellt
P1854R4 C++98 gewöhnliche und breite Zeichenkettenliterale mit nicht kodierbaren
Zeichen waren bedingt unterstützt
Programme mit solchen Literalen sind ill-formed
P2029R4 C++98 1. Es war unklar, ob Zeichenkettenliterale
    nicht kodierbare Zeichen enthalten konnten
2. Es war unklar, ob Zeichenkettenliterale
    numerische Escape-Sequenzen enthalten konnten,
    so dass die von ihnen dargestellten Code Units nicht
    im Array-Element-Typ des Literals darstellbar sind
1. bedingt unterstützt für
    gewöhnliche und breite Zeichenkettenliterale[1]
2. ill-formed, wenn die Code Units
    weder im vorzeichenlosen Ganzzahltyp darstellbar sind,
    der dem zugrundeliegenden Typ entspricht
    oder dem zugrundeliegenden Typ.
  1. P1854R4 wurde später als DR akzeptiert und überschrieb diese Auflösung.

[bearbeiten] Referenzen

  • C++23 Standard (ISO/IEC 14882:2024)
  • 5.13.5 Zeichenkettenliterale [lex.string]
  • C++20 Standard (ISO/IEC 14882:2020)
  • 5.13.5 Zeichenkettenliterale [lex.string]
  • C++17 Standard (ISO/IEC 14882:2017)
  • 5.13.5 Zeichenkettenliterale [lex.string]
  • C++14 Standard (ISO/IEC 14882:2014)
  • 2.14.5 Zeichenkettenliterale [lex.string]
  • C++11 Standard (ISO/IEC 14882:2011)
  • 2.14.5 Zeichenkettenliterale [lex.string]
  • C++03-Standard (ISO/IEC 14882:2003)
  • 2.13.4 Zeichenkettenliterale [lex.string]
  • C++98 Standard (ISO/IEC 14882:1998)
  • 2.13.4 Zeichenkettenliterale [lex.string]

[bearbeiten] Siehe auch

benutzerdefinierte Literale(C++11) Literale mit benutzerdefiniertem Suffix[bearbeiten]
C-Dokumentation für Zeichenkettenliterale