Sonderzeichen in Zeichenfolgenliteralen in C++ (Sonderzeichen in Zeichenfolgenliteralen in C++), Lektion, Seite 723636
https://www.purl.org/stefan_ram/pub/sonderzeichen_c++ (Permalink) ist die kanonische URI dieser Seite.
Stefan Ram
C++-Kurs

Sonderzeichen in Zeichenfolgenliteralen in C++ 

main.cpp

#include <iostream>
#include <ostream>
#include <string>

using namespace ::std::literals;

int main() { ::std::cout << "Hallo, Welt"s << "\n"s; }

transcript
Hallo, Welt

Zeichenfolgenliterale in C++ 

Ein Zeichenliteral stellt immer genau ein Zeichen  dar. Soll statt dessen eine Zeichenfolge  durch einen Ausdruck dargestellt werden, so kann ein Zeichenfolgenliteral  verwendet werden. In einfachen Fällen erhält man das Zeichenfolgenliteral aus der Zeichenfolge, indem man diese in Anführungszeichen einschließt.

Die Zeichenfolge „A“
A
Das Literal für die Zeichenfolge „A“
"A"s

Dieses Beispiel zur Zeichenfolge „A“ zeigt deutlich, daß man zwischen einer Zeichenfolge und einem Zeichenfolgenliteral unterscheiden muß, da beide offensichtlich nicht  übereinstimmen.

Außerdem sieht man, daß man zwischen einem Zeichenliteral und einem Zeichenfolgenliteral immer an Hand der verwendeten Anführungszeichen unterscheiden kann, auch wenn man zwischen dem Zeichen „A“ und der Zeichenfolge „A“ sonst nicht unterscheiden kann.

(Manche C++ -Implementationen melden es nicht als Fehler, wenn ein Zeichenliteral mehrere Zeichen enthält, da dies in manchen Implementation eine spezielle Bedeutung hat. Daher muß der Programmierer selber darauf achten, mit Zeichenliteralen nur ein Zeichen darzustellen.)

Das folgende Programmbeispiel zeigt die Verwendung eines Zeichenfolgenliterals mit einem Zeichen in einem Programm.

hallo.cpp

#include <iostream> // ::std::cout
#include <ostream> // <<
#include <string>

using namespace ::std::literals;

int main() { ::std::cout << "A"s << "\n"s; }

::std::cout
A

Das folgende Programmbeispiel zeigt die Verwendung eines Zeichenfolgenliterals mit mehreren Zeichen in einem Programm.

hallo.cpp

#include <iostream> // ::std::cout
#include <ostream> // <<
#include <string>

using namespace ::std::literals;

int main() { ::std::cout << "Hallo!"s << "\n"s; }

::std::cout
Hallo

Auch die leere Zeichenfolge kann durch ein Zeichenfolgenliteral dargestellt werden: Das folgende Programm gibt nur eine Leerzeile aus.

hallo.cpp

#include <iostream> // ::std::cout
#include <ostream> // <<
#include <string>

using namespace ::std::literals;

int main() { ::std::cout << ""s << "\n"s; }

::std::cout

Die Quellzeichen des Zeichenfolgenliterals sind aber nicht immer mit den Zeichen der bezeichneten Zeichenfolge identisch.

Eine Darstellung eines Zeichens in einem Zeichenfolgenliteral kann nicht immer durch das dem Zeichen gleiche Quelltextzeichen erfolgen. Nicht alle Quelltextzeichen sind in einem Zeichenfolgenliteral erlaubt. So darf in einem Zeichenfolgenliteral etwa keine neue Zeile des Quelltextes begonnen werden.

Soll ein Zeilenendzeichen Teil einer Zeichenfolge sein, so ist es im Zeichenfolgenliteral durch den Quelltext »n« im „Steuerzustand“ (oder „Alternativzustand“) anzugeben. Im Steuerzustand kann jedes Zeichen eine „Steuerbedeutung“ oder „alternative Bedeutung“ haben. So bedeutet das Zeichen »n« in einem Zeichenfolgenliteral normalerweise einfach das Zeichen »n«, im Steuerzustand bedeutet es aber ein Zeilenende.

Dazu nimmt man an, daß man am Anfang eines Zeichenfolgenliterals in einem „Grundzustand“ („Normalzustand“) ist. Im Grundzustand steht das Zeichen »n« im Zeichenfolgenliteral für das Zeichen »n« in der Zeichenfolge. Wenn im Grundzustand jedoch der inverse Schrägstrich »\« auftritt, dann werden die nächsten direkt folgende Zeichen als Steuerzeichenfolge interpretiert. Solche Steuerzeichenfolgen haben eine andere Bedeutung als Zeichenfolgen im Grundzustand. Nach dem Ende einer solchen Steuerzeichenfolge gilt wieder der Grundzustand, ohne daß es eines besonderen Zurückschaltens bedarf. Als Steuerzeichenfolge steht »n« für ein Zeilenende  und nicht mehr für den Buchstaben »n«.

Zeichenfolgenliteral
"a\nb"s
Text
a
b

In dem obigen Beispiel schaltet der inverse Schrägstrich »\« in den Steuerzustand um. Das »n« wird dann als Steuerzeichenfolge, in diesem Fall also als Zeilenende, interpretiert. Danach gilt für die Interpretation des »b« stillschweigend wieder der Grundzustand.

Diese Regelung gilt auch für Zeichenliterale, was das »'\n'« erklärt, das bisher schon oft verwendet wurde. Es gibt ein einzelnes Zeichen, nämlich ein Zeilenende an, obwohl zwischen den Apostroph-Zeichen im Quelltext zwei Zeichen stehen. Daher entspricht es den Regeln für ein Zeichenliteral, die verlangen, daß nur genau ein Zeichen mit einem Zeichenliteral angegeben wird.

hallo.cpp

#include <iostream> // ::std::cout
#include <ostream> // <<
#include <string>

using namespace ::std::literals;

int main() { ::std::cout << "Hallo!"s << "\n"s; }

::std::cout
Hallo

Soll ein Anführungszeichen »"« Teil der notierten Zeichenfolge sein, so ist es im Literal im Grundzustand durch den Quelltext »\"« (ein inverser Schrägstrich und ein Anführungszeichen) zu schreiben. Soll ein inverser Schrägstrich »\« in der Zeichenfolge notiert werden, so ist im Grundzustand der Quelltext »\\« (zwei inverse Schrägstrich) zu schreiben.

Literal
"a\"b\\n"s
Zeichenfolge
a"b\n

Man beachte, daß in dem obigen Textliteral die Zeichenfolge "\n" nicht  für ein Zeilenende steht, da der inverse Schrägstrich direkt vor dem Quelltext "n" darin nicht im Grundzustand auftaucht, sondern selber bereits als Steuerzeichen. Daher wäre es falsch, sich einfach zu merken, daß »\n« in einem Textliteral immer  für ein Zeilenende steht. Um die Bedeutung eines Zeichens zu verstehen, muß man immer auch das Zeichen vor ihm berücksichtigen; das gilt auch für einen inversen Schrägstrich.

Verbindung benachbarter Zeichenfolgenliterale

Mehrere direkt aufeinanderfolgende Zeichenfolgenliterale werden zu einer einzigen Zeichenfolge verbunden. Zwischen ihnen kann Leerraum stehen, also auch eine neue Zeile beginnen.

Literale
"a"s "b"s
"c"s
Zeichenfolge
abc

Umlaute, das Eszett und andere Sonderzeichen können in C++  zwar unter vielen Umgebungen verarbeitet werden, werden aber hier zunächst vermieden, weil ihre Verwendung etwas kompliziert sein kann.

Das folgende Beispielprogramm zeigt Zeichenfolgenliterale im Zusammenhang eines vollständigen Programmes.

main.cpp

#include <iostream>
#include <ostream>
#include <string>

using namespace ::std::literals;

int main() { ::std::cout << "// /* Hau"s "s Hof "s "G\nL \"\nS \\ */"s << "\n"s; }

::std::cout
// /* Haus Hof G
L "
S \ */

Die Zeichenpaare, welche sonst einen Kommentar einleiten würden, verlieren diese Sonderbedeutung, wenn sie in einem Textliteral vorkommen. Daher sind Kommentare innerhalb von Textliteralen nicht möglich.

Zitat *

In translation phase 6 (2.2), adjacent string literals are concatenated and user-defined-string-literals are considered string literals for that purpose.“ … „if a string literal is the result of a concatenation involving at least one user-defined-string-literal, all the participating user-defined-string literals shall have the same ud-suffix and that suffix is applied to the result of the concatenation.” 2.13.8p8

Übungsaufgaben

/    Zeichenfolge ausgeben
Schreiben Sie ein Programm, das die Zeichenfolge ausgibt, die unter der Überschrift "Text" steht, indem Sie diesen Text mit einem Textliteral notieren. Das Programm soll also eine Zeile mit 18 Zeichen (und nichts anderes) ausgeben.
Text
"Hallo," sagte er.
/    Programm ausgeben (schwierig)
Schreiben Sie ein C++ -Programm, das den Quelltext des letzten obenstehenden Programms »main.cpp« (fünf Zeilen) ausgibt.

Rohliterale

Ein einfaches Rohliteral beginnt mit »R"(« und endet mit »)"«.

main.cpp

#include <iostream>
#include <ostream>
#include <string>

using namespace ::std::literals;

int main()
{ ::std::cout << R"(abc)"s << "\n"s; }

Protokoll
abc

Inverse Schrägstriche und Anführungszeichen haben in Rohliteralen keine besondere Bedeutung. (Allerdings beendet die spezielle Zeichenfolge »)"« ein Rohliteral.)

main.cpp

#include <iostream>
#include <ostream>
#include <string>

using namespace ::std::literals;

int main()
{ ::std::cout << R"(a\nc"d)"s << "\n"s; }

Protokoll
a\nc"d

Rohliteralen können Zeilenenden direkt enthalten.

main.cpp

#include <iostream>
#include <ostream>
#include <string>

using namespace ::std::literals;

int main()
{ ::std::cout << R"(a
c)"s << "\n"s; }

Protokoll
a
c

Falls ein Rohliteral die Zeichenfolge »)"« enthalten soll, so kann es mit bis zu 16 Zeichen markiert werden, die eine andere Zeichenfolge zum Beenden festlegen können. Im folgenden Beispiel wird »%%%« zur Markierung verwendet, so daß dann nicht mehr »)"«, sondern erst »)%%%"« die Zeichenfolge beendet.

main.cpp

#include <iostream>
#include <ostream>
#include <string>

using namespace ::std::literals;

int main()
{ ::std::cout << R"%%%(R"(a\nc"d)"s)%%%"s << "\n"s; }

Protokoll
R"(a\nc"d)"s

Das folgende Beispielprogramm zeigt die Ausgabe einer Multiplikationstabelle mit einem Zeichenfolgenliteral, das nicht roh ist.

main.cpp

#include <iostream>
#include <ostream>
#include <string>

using namespace ::std::literals;

int main()
{ ::std::cout << /* Multiplikationstabelle */ "\n"s

" 0 1 2 3 4 5 6 7 8 9\n"s
" \n"s
" 0 0 0 0 0 0 0 0 0 0 0\n"s
" 1 0 1 2 3 4 5 6 7 8 9\n"s
" 2 0 2 4 6 8 10 12 14 16 18\n"s
" 3 0 3 6 9 12 15 18 21 24 27\n"s
" 4 0 4 8 12 16 20 24 28 32 36\n"s
" 5 0 5 10 15 20 25 30 35 40 45\n"s
" 6 0 6 12 18 24 30 36 42 48 54\n"s
" 7 0 7 14 21 28 35 42 49 56 63\n"s
" 8 0 8 16 24 32 40 48 56 64 72\n"s
" 9 0 9 18 27 36 45 54 63 72 81\n"s; }

Protokoll

0 1 2 3 4 5 6 7 8 9

0 0 0 0 0 0 0 0 0 0 0
1 0 1 2 3 4 5 6 7 8 9
2 0 2 4 6 8 10 12 14 16 18
3 0 3 6 9 12 15 18 21 24 27
4 0 4 8 12 16 20 24 28 32 36
5 0 5 10 15 20 25 30 35 40 45
6 0 6 12 18 24 30 36 42 48 54
7 0 7 14 21 28 35 42 49 56 63
8 0 8 16 24 32 40 48 56 64 72
9 0 9 18 27 36 45 54 63 72 81

Das folgende Beispielprogramm zeigt die Ausgabe einer Multiplikationstabelle mit einem rohen Zeichenfolgenliteral.

main.cpp

#include <iostream>
#include <ostream>
#include <string>

using namespace ::std::literals;

int main()
{ ::std::cout << R"(
0 1 2 3 4 5 6 7 8 9

0 0 0 0 0 0 0 0 0 0 0
1 0 1 2 3 4 5 6 7 8 9
2 0 2 4 6 8 10 12 14 16 18
3 0 3 6 9 12 15 18 21 24 27
4 0 4 8 12 16 20 24 28 32 36
5 0 5 10 15 20 25 30 35 40 45
6 0 6 12 18 24 30 36 42 48 54
7 0 7 14 21 28 35 42 49 56 63
8 0 8 16 24 32 40 48 56 64 72
9 0 9 18 27 36 45 54 63 72 81
)"; }

Protokoll


0 1 2 3 4 5 6 7 8 9

0 0 0 0 0 0 0 0 0 0 0
1 0 1 2 3 4 5 6 7 8 9
2 0 2 4 6 8 10 12 14 16 18
3 0 3 6 9 12 15 18 21 24 27
4 0 4 8 12 16 20 24 28 32 36
5 0 5 10 15 20 25 30 35 40 45
6 0 6 12 18 24 30 36 42 48 54
7 0 7 14 21 28 35 42 49 56 63
8 0 8 16 24 32 40 48 56 64 72
9 0 9 18 27 36 45 54 63 72 81

Anhang *

Zeichen im Sonderzustand *

In dem Sonderzustand, in den ein einzelner inverser Schrägstrich »\« im Grundzustand umschaltet, haben die folgenden Zeichen Sonderbedeutungen.

Tabelle

Z. Bedeutung Bed. deutschsprachige Bedeutung

" double quote " Anfuehrungszeichen
' single quote ’ Apostroph
? question mark ? Fragezeichen
\ backslash \ inverser Schraegstrich

a alert BEL Alarm (Klangsignal, Glocke)
b backspace BS Rueckschritt (u.U. loeschend)
f form feed FF Formularvorschub
n new-line NL Neue Zeile
r carriage return CR Wagenrücklauf
t horizontal tab HT waagerechter Tabulator
v vertical tab VT senkrechter Tabulator

Trigraphen sind veraltete Notationen für bestimmte Sonderzeichen. Beispielsweise stand der Trigraph »??=« für das Nummernzeichen »#«. Um zu verhindern, daß beispielsweise der Trigraph »??=« als »#« interpretiert wird, wenn wirklich diese drei Zeichen gemeint sind, kann darin das zweite Fragezeichen als »\?« geschrieben werden, so daß »?\?=« für die drei Zeichen »??=« und nicht für das Doppelkreuz »#« steht.

Seiteninformationen und Impressum   |   Mitteilungsformular  |   "ram@zedat.fu-berlin.de" (ohne die Anführungszeichen) ist die Netzpostadresse von Stefan Ram.   |   Eine Verbindung zur Stefan-Ram-Startseite befindet sich oben auf dieser Seite hinter dem Text "Stefan Ram".)  |   Der Urheber dieses Textes ist Stefan Ram. Alle Rechte sind vorbehalten. Diese Seite ist eine Veröffentlichung von Stefan Ram. Schlüsselwörter zu dieser Seite/relevant keywords describing this page: Stefan Ram Berlin slrprd slrprd stefanramberlin spellched stefanram723636 stefan_ram:723636 Sonderzeichen in Zeichenfolgenliteralen in C++ Stefan Ram, Berlin, and, or, near, uni, online, slrprd, slrprdqxx, slrprddoc, slrprd723636, slrprddef723636, PbclevtugFgrsnaEnz Erklärung, Beschreibung, Info, Information, Hinweis,

Der Urheber dieses Textes ist Stefan Ram. Alle Rechte sind vorbehalten. Diese Seite ist eine Veröffentlichung von Stefan Ram.
https://www.purl.org/stefan_ram/pub/sonderzeichen_c++