C++-Literal für mehrzeilige Zeichenfolgen

Lesezeit: 8 Minuten

C Literal fur mehrzeilige Zeichenfolgen
rlbond

Gibt es eine Möglichkeit, mehrzeilige Klartext-Konstantenliterale in C++ à la Perl zu haben? Vielleicht irgendein Parsing-Trick mit #includeeine Datei? Mir fällt keins ein, aber Junge, das wäre schön. Ich weiß, dass es in C++0x sein wird.

  • Im Allgemeinen möchten Sie keine Zeichenfolgenliterale in Code einbetten. Für I18N und L10N ist es vorzuziehen, Zeichenfolgenliterale in eine Konfigurationsdatei einzufügen, die zur Laufzeit geladen wird.

    – Martin York

    16. Juli 2009 um 7:09 Uhr

  • Es gibt genug Fälle, in denen das Einfügen von Zeichenfolgenliteralen in Code kein Problem darstellt: wenn die Zeichenfolge nicht verwendet wird, um sie dem Benutzer darzustellen; dh: SQL-Anweisungen, Dateinamen, Registrierungsschlüsselnamen, auszuführende Befehlszeilen, …

    – mmmmmmmm

    16. Juli 2009 um 7:18 Uhr

  • @Martin: Es kann trotzdem nützlich sein, es zu wissen. Ich habe es zum Beispiel getan, um komplexe reguläre Ausdrücke aufzubrechen.

    – Boojum

    16. Juli 2009 um 7:22 Uhr

C Literal fur mehrzeilige Zeichenfolgen
entspannen

Naja, so ungefähr. Am einfachsten ist es, einfach die Tatsache zu nutzen, dass benachbarte Zeichenfolgenliterale vom Compiler verkettet werden:

const char *text =
  "This text is pretty long, but will be "
  "concatenated into just a single string. "
  "The disadvantage is that you have to quote "
  "each part, and newlines must be literal as "
  "usual.";

Die Einrückung spielt keine Rolle, da sie nicht innerhalb der Anführungszeichen steht.

Sie können dies auch tun, solange Sie darauf achten, den eingebetteten Zeilenumbruch zu maskieren. Andernfalls wird nicht kompiliert, wie es meine erste Antwort getan hat:

const char *text2 =
  "Here, on the other hand, I've gone crazy \
and really let the literal span several lines, \
without bothering with quoting each line's \
content. This works, but you can't indent.";

Beachten Sie auch hier diese Backslashes am Ende jeder Zeile, sie müssen unmittelbar vor dem Zeilenende stehen, sie maskieren den Zeilenumbruch in der Quelle, sodass alles so wirkt, als wäre der Zeilenumbruch nicht vorhanden. Sie erhalten keine Zeilenumbrüche in der Zeichenfolge an den Stellen, an denen Sie Backslashes hatten. Mit dieser Form können Sie den Text offensichtlich nicht einrücken, da die Einrückung dann Teil des Strings werden und ihn mit zufälligen Leerzeichen verstümmeln würde.

  • Mir wurde in der Vergangenheit gesagt, dass die erste Option an der Implementierung liegen kann, aber ich habe noch keinen Compiler gefunden, der diese Syntax nicht berücksichtigt.

    – Jason Mock

    22. Oktober 2010 um 18:48 Uhr

  • @Jason: Es war nicht unbedingt ein Teil von Pre-C89-Compilern, aber es ist in C89 definiert und wird daher im Wesentlichen überall unterstützt.

    – Jonathan Leffler

    4. April 2011 um 14:25 Uhr

  • Wenn Sie wirklich möchten, dass die Zeichenfolge in c++98 in mehreren Zeilen formatiert wird, ersetzen Sie einfach \n für das abschließende Leerzeichen in jedem Zeichenfolgenfragment in Anführungszeichen. C++11-Rohliterale sind immer noch mein Favorit.

    – Emsr

    22. September 2011 um 3:46 Uhr

  • @unwind Beachten Sie, dass der Zeilenumbruch am Ende der Quellzeile nicht Teil der Zeichenfolge ist, sondern nur übersprungen wird. Wenn Sie einen Zeilenumbruch als Teil der Zeichenfolge wünschen, müssen Sie \n\ am Ende der Zeile haben.

    – Hyde

    21. April 2013 um 7:39 Uhr


  • Es gibt einen bösen Fehler in Microsoft Visual Studio. Wenn Sie am Zeilenende Backslashes verwenden, wird der Text automatisch in die Zeichenfolge eingerückt.

    – palota

    19. Januar 2014 um 21:18 Uhr

1646631018 351 C Literal fur mehrzeilige Zeichenfolgen
emsr

In C++11 haben Sie rohe Zeichenfolgenliterale. So ähnlich wie hier-Text in Shells und Skriptsprachen wie Python und Perl und Ruby.

const char * vogon_poem = R"V0G0N(
             O freddled gruntbuggly thy micturations are to me
                 As plured gabbleblochits on a lurgid bee.
              Groop, I implore thee my foonting turlingdromes.   
           And hooptiously drangle me with crinkly bindlewurdles,
Or I will rend thee in the gobberwarts with my blurlecruncheon, see if I don't.

                (by Prostetnic Vogon Jeltz; see p. 56/57)
)V0G0N";

Alle Leerzeichen und Einrückungen sowie die Zeilenumbrüche in der Zeichenfolge bleiben erhalten.

Diese können auch utf-8|16|32 oder wchar_t (mit den üblichen Präfixen) sein.

Ich sollte darauf hinweisen, dass die Escape-Sequenz V0G0N hier eigentlich nicht benötigt wird. Seine Anwesenheit würde es ermöglichen, )” in die Zeichenfolge zu setzen. Mit anderen Worten, ich hätte setzen können

                "(by Prostetnic Vogon Jeltz; see p. 56/57)"

(beachten Sie zusätzliche Anführungszeichen) und die obige Zeichenfolge wäre immer noch korrekt. Sonst hätte ich genauso gut gebrauchen können

const char * vogon_poem = R"( ... )";

Die Klammern direkt in den Anführungszeichen werden noch benötigt.

  • Das ist wirklich, was ich will, die Möglichkeit, Anführungszeichen, Backslash-Ns, Escapes zu vermeiden und immer noch Zeilenumbrüche in der eigentlichen Zeichenfolge erscheinen zu lassen. Dies ist praktisch für eingebetteten Code (z. B. Shader oder Lua). Leider verwenden wir noch nicht alle C++-0x. 🙁

    – mlepage

    18. Juli 2012 um 14:40 Uhr

  • Ich habe dies selbst für eingebettete SQL- und Python-Skripte in Betracht gezogen. Ich hatte für Sie gehofft, ob gcc es vielleicht im C++98-Modus durchgleiten lassen würde, aber leider nein.

    – Emsr

    18. Juli 2012 um 15:16 Uhr

  • Ich bin mehr an clang und gcc gewöhnt. In diesen Compilern müssen Sie ein Flag für C++0x oder c++11 setzen. Auf der MS-Website sieht es so aus, als hätten sie noch keine Rohliterale. Ich verstehe, dass MS neue Compiler-Updates schneller veröffentlichen wird, wenn C++-Features implementiert werden. Suchen Sie nach Visual C++ Compiler November 2012 CTP [microsoft.com/en-us/download/details.aspx?id=35515] für die neueste Blutung.

    – Emsr

    31. Januar 2013 um 1:17 Uhr

  • @rsethc Verwenden Sie einfach #if 0#endif Codeblöcke auskommentieren. Auch Nester.

    – Bobbogo

    12. September 2017 um 17:23 Uhr


  • Meine mehrzeiligen Zeichenfolgen verwenden immer V0G0N, weil ich mir diese Syntax nie merken kann, und deshalb schaue ich immer diese Antwort nach, und dann bin ich immer amüsiert.

    – bhaller

    21. Januar 2021 um 22:37 Uhr

Sie können dies auch tun:

const char *longString = R""""(
This is 
a very 
long 
string
)"""";

  • danke, das ist großartig, funktioniert sogar in C. offensichtlich, char longString[] = R""""( This is a very long string )""""; funktioniert auch, bei mir.

    – kämpfender_Lerner

    15. Juni 2019 um 18:02 Uhr

  • Beginnt und endet die Zeichenfolge mit einer neuen Zeile?

    – Tim MB

    5. Oktober 2019 um 9:51 Uhr


  • Es ist ein rohes Zeichenfolgenliteral. Verfügbar seit C++11.

    – Nikolasan

    25. Januar 2020 um 0:57 Uhr

  • funktioniert mit Arduino! Jetzt kann ich problemlos eingebettete Webseiten bereitstellen!

    – nmz787

    19. Juli 2020 um 9:52 Uhr

  • Eine nette Variation von @emsr, die zeigt, dass seine Antwort weniger wie PERL und mehr wie Python aussehen kann.

    – automorph

    18. Dezember 2020 um 1:46 Uhr

#define MULTILINE(...) #__VA_ARGS__

Verbraucht alles zwischen den Klammern.
Ersetzt beliebig viele aufeinanderfolgende Whitespace-Zeichen durch ein einzelnes Leerzeichen.

1646631020 698 C Literal fur mehrzeilige Zeichenfolgen
bcmpinc

Eine wahrscheinlich bequeme Möglichkeit, mehrzeilige Zeichenfolgen einzugeben, ist die Verwendung von Makros. Dies funktioniert nur, wenn Anführungszeichen und Klammern ausgeglichen sind und keine Kommas der obersten Ebene enthalten:

#define MULTI_LINE_STRING(a) #a
const char *text = MULTI_LINE_STRING(
  Using this trick(,) you don't need to use quotes.
  Though newlines and     multiple     white   spaces
  will be replaced by a single whitespace.
);
printf("[[%s]]\n",text);

Kompiliert mit gcc 4.6 oder g++ 4.6 ergibt dies: [[Using this trick(,) you don't need to use quotes. Though newlines and multiple white spaces will be replaced by a single whitespace.]]

Notiere dass der , darf nicht in der Zeichenfolge enthalten sein, es sei denn, es ist in Klammern oder Anführungszeichen enthalten. Einfache Anführungszeichen sind möglich, erzeugen aber Compiler-Warnungen.

Bearbeiten: Wie in den Kommentaren erwähnt, #define MULTI_LINE_STRING(...) #__VA_ARGS__ ermöglicht die Verwendung von ,.

  • Für ein Projekt, in das ich einige Lua-Code-Snippets in C++ einbinden wollte, schrieb ich schließlich ein kleines Python-Skript, in das ich die mehrzeiligen Zeichenfolgen eingab, und ließ daraus eine C++-Quelldatei generieren.

    – bcmpinc

    16. Juli 2012 um 16:39 Uhr

  • Perfekt für mich, das Hinzufügen einer riesigen mehrzeiligen Float-List-Zeichenfolge aus einer Collada-Datei für Unit-Tests. Ich hatte keine Lust, überall Anführungszeichen zu setzen, ich brauchte eine Copy&Paste-Lösung.

    – Soylent Graham

    1. August 2012 um 11:39 Uhr

  • Sie können verwenden #define MULTILINE(...) #__VA_ARGS__ wenn Sie möchten, dass Ihre Zeichenfolge Kommas enthält.

    – Simon

    1. Juli 2013 um 14:09 Uhr

  • Beachten Sie, dass dadurch die meisten zusätzlichen Leerzeichen entfernt werden (einschließlich aller \n und \r), was für einige Fälle praktisch und für andere fatal ist.

    – BKS

    8. Oktober 2013 um 21:35 Uhr

Sie können einfach dies tun:

const char *text = "This is my string it is "
     "very long";

  • Für ein Projekt, in das ich einige Lua-Code-Snippets in C++ einbinden wollte, schrieb ich schließlich ein kleines Python-Skript, in das ich die mehrzeiligen Zeichenfolgen eingab, und ließ daraus eine C++-Quelldatei generieren.

    – bcmpinc

    16. Juli 2012 um 16:39 Uhr

  • Perfekt für mich, das Hinzufügen einer riesigen mehrzeiligen Float-List-Zeichenfolge aus einer Collada-Datei für Unit-Tests. Ich hatte keine Lust, überall Anführungszeichen zu setzen, ich brauchte eine Copy&Paste-Lösung.

    – Soylent Graham

    1. August 2012 um 11:39 Uhr

  • Sie können verwenden #define MULTILINE(...) #__VA_ARGS__ wenn Sie möchten, dass Ihre Zeichenfolge Kommas enthält.

    – Simon

    1. Juli 2013 um 14:09 Uhr

  • Beachten Sie, dass dadurch die meisten zusätzlichen Leerzeichen entfernt werden (einschließlich aller \n und \r), was für einige Fälle praktisch und für andere fatal ist.

    – BKS

    8. Oktober 2013 um 21:35 Uhr

C Literal fur mehrzeilige Zeichenfolgen
CXJ

Nur um den Kommentar von @emsr in der Antwort von @unwind etwas zu verdeutlichen, wenn man nicht das Glück hat, einen C ++ 11-Compiler (z. B. GCC 4.2.1) zu haben, und man die Zeilenumbrüche in die Zeichenfolge einbetten möchte (entweder char * oder Klassenstring), kann man etwa so schreiben:

const char *text =
  "This text is pretty long, but will be\n"
  "concatenated into just a single string.\n"
  "The disadvantage is that you have to quote\n"
  "each part, and newlines must be literal as\n"
  "usual.";

Sehr offensichtlich, stimmt, aber der kurze Kommentar von @emsr ist mir beim ersten Lesen nicht aufgefallen, also musste ich das für mich selbst entdecken. Hoffentlich habe ich jemand anderem ein paar Minuten erspart.

963180cookie-checkC++-Literal für mehrzeilige Zeichenfolgen

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy