Gibt es eine Möglichkeit, mehrzeilige Klartext-Konstantenliterale in C++ à la Perl zu haben? Vielleicht irgendein Parsing-Trick mit #include
eine Datei? Mir fällt keins ein, aber Junge, das wäre schön. Ich weiß, dass es in C++0x sein wird.
C++-Literal für mehrzeilige Zeichenfolgen
rlbond
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
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.
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
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.
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