Namespaces
Variants

String literal

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

Inhaltsverzeichnis

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)

Erklärung

s-char-seq - Eine Sequenz aus einem oder mehreren s-char s
s-char - Eines der folgenden:
basic-s-char - Ein Zeichen aus dem basic source character set (until C++23) translation character set (since C++23) , außer dem doppelten Anführungszeichen " , dem Backslash \ oder dem Zeilenumbruchzeichen
d-char-seq - Eine Sequenz aus einem oder mehreren d-char s, maximal 16 Zeichen lang
d-char - Ein Zeichen aus dem basic source character set (until C++23) basic character set (since C++23) , außer Klammern, Backslash und Leerzeichen
r-char-seq - Eine Sequenz aus einem oder mehreren r-char s, die jedoch nicht die Abschlusssequenz ) d-char-seq " enthalten darf
r-char - Ein Zeichen aus dem basic source character set (until C++23) translation character set (since C++23)

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

const char [ N ]

(bis C++20)

const char8_t [ N ]

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

In den in der obigen Tabelle aufgeführten Typen ist N die Anzahl der kodierten Codeeinheiten, die unten bestimmt wird.

Gewöhnliche und UTF-8 (since C++11) String-Literale werden zusammen als schmale String-Literale bezeichnet.

Die Auswertung eines String-Literals ergibt ein String-Literal-Objekt mit statischer Speicherdauer . Ob alle String-Literale in sich nicht überlappenden Objekten gespeichert werden und ob aufeinanderfolgende Auswertungen eines String-Literals dasselbe oder ein unterschiedliches Objekt ergeben, ist nicht spezifiziert.

Der Effekt eines Versuchs, ein String-Literal-Objekt zu modifizieren, ist undefiniert.

bool b = "bar" == 3 + "foobar"; // kann true oder false sein, nicht spezifiziert
const char* pc = "Hello";
char* p = const_cast<char*>(pc);
p[0] = 'M'; // undefiniertes Verhalten

Raw-String-Literale

Raw-String-Literale sind String-Literale mit einem Präfix, das R enthält (Syntaxen (2,4,6,8,10) ). Sie escapen keine Zeichen, was bedeutet, dass alles zwischen den Begrenzern d-char-seq  ( und ) d-char-seq Teil des Strings wird. Die abschließende d-char-seq ist dieselbe Zeichensequenz wie die initiale 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)

Initialisierung

String-Literal-Objekte werden mit der Folge von Codeeinheitenwerten initialisiert, die der Folge von s-char s und r-char s (since C++11) , plus einem abschließenden Nullzeichen (U+0000), in der folgenden Reihenfolge entspricht:

1) Für jede zusammenhängende Sequenz von basic-s-char s, r-char s, (since C++11) einfachen Escape-Sequenzen und universellen Zeichennamen wird die Sequenz der Zeichen, die sie bezeichnet, unter Verwendung der assoziierten Zeichenkodierung des String-Literals in eine Codeeinheit-Sequenz kodiert. Wenn ein Zeichen in der assoziierten Zeichenkodierung keine Darstellung besitzt, ist das Programm fehlerhaft.
Wenn die zugehörige Zeichenkodierung zustandsbehaftet ist, wird die erste solche Sequenz beginnend mit dem anfänglichen Kodierungszustand kodiert und jede nachfolgende Sequenz wird beginnend mit dem finalen Kodierungszustand der vorherigen Sequenz kodiert.
2) Für jede numerische Escape-Sequenz , wobei v der durch die oktale oder hexadezimale Zahl repräsentierte ganzzahlige Wert ist, der die Ziffernfolge der Escape-Sequenz umfasst, und T der Array-Elementtyp des Zeichenkettenliterals ist (siehe Tabelle oben ):
  • Wenn v den Bereich der darstellbaren Werte von T nicht überschreitet, dann trägt die Escape-Sequenz eine einzelne Codeeinheit mit dem Wert v bei.
  • Andernfalls, wenn das Zeichenkettenliteral der Syntax (1) oder (3) entspricht, 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 Codeeinheit mit einem eindeutigen Wert des Typs T bei, der kongruent zu v mod 2 S
    ist, wobei S die Breite von T ist.
  • Andernfalls ist das Programm fehlerhaft.
Wenn die zugehörige Zeichenkodierung zustandsbehaftet ist, haben alle derartigen Sequenzen keine Auswirkung auf den Kodierungszustand.
3) Jede bedingte Escape-Sequenz trägt eine implementierungsdefinierte Codeeinheitenfolge bei.
Wenn die zugehörige Zeichenkodierung zustandsbehaftet ist, ist implementierungsdefiniert, welche Auswirkungen diese Sequenzen auf den Kodierungszustand haben.

Verkettung

Benachbarte String-Literale werden in der Übersetzungsphase 6 (nach der Präprozessierung) verkettet:

  • Wenn die beiden Zeichenkettenliterale vom selben Typ sind, dann ist das verkettete Zeichenkettenliteral ebenfalls von diesem Typ.
  • Wenn ein gewöhnliches Zeichenkettenliteral neben einem breiten Zeichenkettenliteral steht, ist das Verhalten undefiniert.
(bis C++11)
  • Wenn ein gewöhnliches Zeichenkettenliteral neben einem nicht-gewöhnlichen Zeichenkettenliteral steht, ist das verkettete Zeichenkettenliteral vom Typ des letzteren.
  • Wenn ein UTF-8-Zeichenkettenliteral neben einem breiten Zeichenkettenliteral steht, ist das Programm fehlerhaft.
  • Jede andere Kombination ist bedingt unterstützt mit implementierungsdefinierter Semantik. [1]
(bis C++23)
  • Jede andere Kombination ist fehlerhaft.
(seit C++23)
(seit C++11)
"Hello, " "world!" // in Phase 6 bilden die 2 String-Literale "Hello, world!"
L"Δx = %" PRId16   // in Phase 4 wird PRId16 zu "d" expandiert
                   // in Phase 6 bilden L"Δx = %" und "d" L"Δx = %d"
  1. Keine bekannte Implementierung unterstützt eine solche Verkettung.

Nicht ausgewertete Zeichenketten

Die folgenden Kontexte erwarten ein String-Literal, werten es jedoch nicht aus:

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


Es ist nicht spezifiziert, ob nicht-ordinäre String-Literale in diesen Kontexten erlaubt sind , außer dass ein Literal-Operator-Name ein ordinäres String-Literal verwenden muss (seit C++11) .

(bis C++26)

In diesen Kontexten sind nur ordinäre String-Literale erlaubt.

Jeder Universal Character Name und jede einfache Escape-Sequenz in einem nicht-ausgewerteten String wird durch das Mitglied des Übersetzungs-Zeichensatzes ersetzt, das es bezeichnet. Ein nicht-ausgewerteter String, der eine numerische Escape-Sequenz oder eine bedingte Escape-Sequenz enthält, ist fehlerhaft.

(seit C++26)

Hinweise

String-Literale können verwendet werden, um Zeichenarrays zu initialisieren . Wenn ein Array wie char str [ ] = "foo" ; initialisiert wird, str wird eine Kopie des Strings "foo" enthalten.

String-Literale sind konvertierbar und zuweisbar an nicht-konstante char * oder wchar_t * , um Kompatibilität mit C zu gewährleisten, wo String-Literale vom Typ char [ N ] und wchar_t [ N ] sind. Eine solche implizite Konvertierung ist als veraltet markiert.

(bis C++11)

String-Literale sind nicht konvertierbar oder zuweisbar an nicht-konstante CharT* . Eine explizite Konvertierung (z.B. const_cast ) muss verwendet werden, falls eine solche Konvertierung gewünscht ist.

(seit C++11)

Ein String-Literal ist nicht notwendigerweise eine nullterminierte Zeichenfolge: Wenn ein String-Literal 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, aber das Array hat die Größe 8

Wenn auf eine hexadezimale Escape-Sequenz in einem String-Literal eine gültige hexadezimale Ziffer folgt, würde dies als ungültige Escape-Sequenz zu einem Kompilierungsfehler führen. String-Konkatenation kann als Workaround verwendet werden:

//const char* p = "\xfff"; // Fehler: Hexadezimale Escape-Sequenz außerhalb des gültigen Bereichs
const char* p = "\xff""f"; // OK: das Literal ist const char[3] mit {'\xff','f','\0'}
Feature-Test Makro Wert Std Funktion
__cpp_char8_t 202207L (C++23)
(DR20)
char8_t Kompatibilitäts- und Portabilitätskorrektur (erlaubt Initialisierung von ( unsigned ) char Arrays aus UTF-8 String-Literalen)
__cpp_raw_strings 200710L (C++11) Raw-String-Literale
__cpp_unicode_literals 200710L (C++11) Unicode-String-Literale

Beispiel

#include <iostream>
// array1 und array2 enthalten dieselben Werte:
char array1[] = "Foo" "bar";
char array2[] = {'F', 'o', 'o', 'b', 'a', 'r', '\0'};
const char* s1 = R"foo(
Hello
  World
)foo";
// gleich wie
const char* s2 = "\nHello\n  World\n";
// gleich wie
const char* s3 = "\n"
                 "Hello\n"
                 "  World\n";
const wchar_t* s4 = L"ABC" L"DEF"; // OK, gleich wie
const wchar_t* s5 = L"ABCDEF";
const char32_t* s6 = U"GHI" "JKL"; // OK, gleich wie
const char32_t* s7 = U"GHIJKL";
const char16_t* s9 = "MN" u"OP" "QR"; // OK, gleich wie
const char16_t* sA = u"MNOPQR";
// const auto* sB = u"Mixed" U"Types";
        // vor C++23 möglicherweise durch die Implementierung unterstützt oder nicht;
        // seit C++23 ungültig
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

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 String-Literalen war es
nicht erlaubt, auf mehrere Code-Einheiten abzubilden
erlaubt
CWG 1656
( P2029R4 )
C++98 die durch numerische Escape-Sequenzen
in String-Literalen bezeichneten Zeichen waren unklar
klargestellt
CWG 1759 C++11 ein UTF-8-String-Literal könnte Code-Einheiten
enthalten, die nicht in char darstellbar sind
char kann alle UTF-8-Code-Einheiten darstellen
CWG 1823 C++98 ob String-Literale unterschiedlich sind,
war implementierungsdefiniert
Unterscheidbarkeit ist unspezifiziert, und dasselbe
String-Literal kann unterschiedliche Objekte ergeben
CWG 2333
( P2029R4 )
C++11 es war unklar, ob numerische Escape-Sequenzen
in UTF-8/16/32-String-Literalen erlaubt waren
klargestellt
CWG 2870 C++11 das Verkettungsergebnis von zwei
gewöhnlichen String-Literalen war unklar
klargestellt
P1854R4 C++98 gewöhnliche und breite String-Literale mit nicht kodierbaren
Zeichen waren bedingt unterstützt
Programme mit solchen Literalen sind fehlerhaft
P2029R4 C++98 1. es war unklar, ob String-Literale
nicht kodierbare Zeichen enthalten können
2. es war unklar, ob String-Literale numerische
Escape-Sequenzen enthalten können, bei denen
die Code-Einheiten, die sie repräsentieren, nicht
im Array-Elementtyp der Literale darstellbar sind
1. für gewöhnliche und breite String-Literale
als bedingt unterstützt festgelegt [1]
2. fehlerhaft, wenn die Code-Einheiten
weder im vorzeichenlosen Ganzzahltyp
entsprechend dem zugrundeliegenden Typ
darstellbar sind
  1. P1854R4 wurde später als DR angenommen und überschreibt diese Resolution.

Referenzen

  • C++23-Standard (ISO/IEC 14882:2024):
  • 5.13.5 Zeichenkettenliterale [lex.string]
  • C++20-Standard (ISO/IEC 14882:2020):
  • 5.13.5 String-Literale [lex.string]
  • C++17-Standard (ISO/IEC 14882:2017):
  • 5.13.5 Stringliterale [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]

Siehe auch

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