it-swarm.com.de

Regeln für Escape-Zeichen für C++ - String-Literale

Welche Regeln gelten für das Escape-Zeichen \ in String-Literalen? Gibt es eine Liste aller Zeichen, für die Escapezeichen vorhanden sind?

Wenn ich \ in einem String-Literal in gedit verwende und es mit drei beliebigen Zahlen folge, färbt es sie anders.

Ich habe versucht, einen std::string zu erstellen, der aus einem Literal mit dem Zeichen 0, gefolgt von dem Nullzeichen (\0), gefolgt von dem Zeichen 0 erstellt wurde. Die Hervorhebung der Syntax hat mich jedoch darauf aufmerksam gemacht, dass dadurch möglicherweise etwas wie das Zeichen 0 gefolgt von dem Nullzeichen (\00, aka \0) entsteht, das heißt nur zwei Zeichen.

Für die Lösung nur dieses einen Problems ist dies der beste Weg, dies zu tun:

std::string ("0\0" "0", 3)  // String concatenation 

Und gibt es einen Hinweis darauf, was das Fluchtzeichen generell in String-Literalen tut? Was ist zum Beispiel "\ a"?

37
David Stone

Steuerzeichen:

(Hex-Codes setzen eine ASCII-kompatible Zeichencodierung voraus.)

  • \a = \x07 = alarm (Glocke)
  • \b = \x08 = Rücktaste
  • \t = \x09 = Horizontale Registerkarte
  • \n = \x0A = Zeilenvorschub (oder Zeilenvorschub)
  • \v = \x0B = vertikale Registerkarte
  • \f = \x0C = Formularvorschub
  • \r = \x0D = Wagenrücklauf
  • \e = \x1B = escape (nicht standardmäßige GCC-Erweiterung)

Satzzeichen:

  • \" = Anführungszeichen (für '"' ist kein Backslash erforderlich)
  • \' = Apostroph (Backslash für "'" nicht erforderlich)
  • \? = Fragezeichen (zur Vermeidung von Trigraphen)
  • \\ = umgekehrter Schrägstrich

Numerische Zeichenreferenzen:

  • \ + bis zu 3 Oktalstellen
  • \x + beliebig viele hexadezimale Ziffern
  • \u + 4 Hex-Ziffern (Unicode BMP, neu in C++ 11)
  • \U + 8 hexadezimale Ziffern (Unicode-Astralebenen, neu in C++ 11)

\0 = \00 = \000 = oktaler Code für Nullzeichen

Wenn Sie nach einem \0 ein tatsächliches Ziffernzeichen wünschen, dann empfehle ich die Verkettung von Zeichenfolgen. Beachten Sie, dass der Leerraum zwischen den Teilen des Literal optional ist. Sie können also "\0""0" schreiben.

55
dan04

\a ist das Klingel-/Alarmzeichen, das bei manchen Systemen einen Ton auslöst. \nnn steht für ein beliebiges Zeichen ASCII in Oktalbasis. \0 ist jedoch insofern speziell, als es das Nullzeichen darstellt, egal was passiert.

Um Ihre ursprüngliche Frage zu beantworten, können Sie auch die 0-Zeichen als:

std::string ("\060\000\060", 3);

(da eine ASCII '0' in Oktal 60 ist)

Die MSDN-Dokumentation enthält einen ziemlich ausführlichen Artikel dazu sowie cppreference .

4
jli

\ 0 wird als eine oktale Escape-Sequenz interpretiert, wenn auf andere Ziffern gefolgt wird.\00 wird also als einzelnes Zeichen interpretiert. (\ 0 ist technisch gesehen auch eine oktale Escape-Sequenz, zumindest in C).

So wie du es machst:

std::string ("0\0" "0", 3)  // String concatenation 

funktioniert, weil diese Version des Konstruktors ein Char-Array benötigt; Wenn Sie versuchen, "0\0" "0" einfach als const char * zu übergeben, wird es als C-String behandelt und nur bis zum Nullzeichen kopiert.

Hier ist eine Liste von Escape-Sequenzen .

4
mgiuffrida

Ich habe so etwas als Kommentar hinterlassen, aber ich glaube, es braucht wahrscheinlich mehr Sichtbarkeit, da keine der Antworten diese Methode erwähnt:

Die Methode, die ich jetzt zum Initialisieren eines std::string mit nicht druckenden Zeichen (und insbesondere eingebetteten Nullzeichen) vorziehen möchte, ist die Verwendung der C++ 11-Funktion von Initialisierungslisten.

std::string const str({'\0', '6', '\a', 'H', '\t'});

Ich muss keine fehleranfällige manuelle Zählung der Anzahl der verwendeten Zeichen durchführen. Wenn ich später irgendwo in der Mitte ein '\ 013' einfügen möchte, kann ich und der gesamte Code funktioniert weiterhin . Das Problem der falschen Fluchtsequenz wird versehentlich vollständig umgangen.

Der einzige Nachteil sind alle diese zusätzlichen '- und ,-Zeichen.

1
David Stone

Mit der Magie der benutzerdefinierten Literale haben wir eine weitere Lösung dafür. C++ 14 fügte einen std::string-Literaloperator hinzu.

using namespace std::string_literals;
auto const x = "\0" "0"s;

Konstruiert eine Zeichenfolge der Länge 2 mit einem '\ 0'-Zeichen (Null), gefolgt von einem' 0'-Zeichen (der Ziffer Null). Ich bin nicht sicher, ob es mehr oder weniger klar ist als der initializer_list<char>Konstruktor-Ansatz , aber es werden zumindest die '- und ,-Zeichen entfernt.

0
David Stone