C++ multiline string literal

C++String Literals

C++ Problem Overview


Is there any way to have multi-line plain-text, constant literals in C++, à la Perl? Maybe some parsing trick with #includeing a file? I can't think of one, but boy, that would be nice. I know it'll be in C++0x.

C++ Solutions


Solution 1 - C++

Well ... Sort of. The easiest is to just use the fact that adjacent string literals are concatenated by the compiler:

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.";

The indentation doesn't matter, since it's not inside the quotes.

You can also do this, as long as you take care to escape the embedded newline. Failure to do so, like my first answer did, will not compile:

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.";
Again, note those backslashes at the end of each line, they must be immediately before the line ends, they are escaping the newline in the source, so that everything acts as if the newline wasn't there. You don't get newlines in the string at the locations where you had backslashes. With this form, you obviously can't indent the text since the indentation would then become part of the string, garbling it with random spaces.

Solution 2 - C++

In C++11 you have raw string literals. Sort of like here-text in shells and script languages like Python and Perl and 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";

All the spaces and indentation and the newlines in the string are preserved.

These can also be utf-8|16|32 or wchar_t (with the usual prefixes).

I should point out that the escape sequence, V0G0N, is not actually needed here. Its presence would allow putting )" inside the string. In other words, I could have put

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

(note extra quotes) and the string above would still be correct. Otherwise I could just as well have used

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

The parens just inside the quotes are still needed.

Solution 3 - C++

You can also do this:

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

Solution 4 - C++

#define MULTILINE(...) #__VA_ARGS__
Consumes everything between the parentheses.
Replaces any number of consecutive whitespace characters by a single space.

Solution 5 - C++

A probably convenient way to enter multi-line strings is by using macro's. This only works if quotes and parentheses are balanced and it does not contain 'top level' comma's:

#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);

Compiled with gcc 4.6 or g++ 4.6, this produces: [[Using this trick(,) you don't need to use quotes. Though newlines and multiple white spaces will be replaced by a single whitespace.]]

Note that the , cannot be in the string, unless it is contained within parenthesis or quotes. Single quotes is possible, but creates compiler warnings.

Edit: As mentioned in the comments, #define MULTI_LINE_STRING(...) #__VA_ARGS__ allows the use of ,.

Solution 6 - C++

You can just do this:

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

Solution 7 - C++

Just to elucidate a bit on @emsr's comment in @unwind's answer, if one is not fortunate enough to have a C++11 compiler (say GCC 4.2.1), and one wants to embed the newlines in the string (either char * or class string), one can write something like this:

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.";

Very obvious, true, but @emsr's short comment didn't jump out at me when I read this the first time, so I had to discover this for myself. Hopefully, I've saved someone else a few minutes.

Solution 8 - C++

Since an ounce of experience is worth a ton of theory, I tried a little test program for MULTILINE:

#define MULTILINE(...) #__VA_ARGS__

const char *mstr[] =
{
	MULTILINE(1, 2, 3),       // "1, 2, 3"
	MULTILINE(1,2,3),         // "1,2,3"
	MULTILINE(1 , 2 , 3),     // "1 , 2 , 3"
	MULTILINE( 1 , 2 , 3 ),   // "1 , 2 , 3"
	MULTILINE((1,  2,  3)),   // "(1,  2,  3)"
	MULTILINE(1
	          2
	          3),             // "1 2 3"
	MULTILINE(1\n2\n3\n),     // "1\n2\n3\n"
	MULTILINE(1\n
              2\n
              3\n),           // "1\n 2\n 3\n"
	MULTILINE(1, "2" \3)      // "1, \"2\" \3"
};

Compile this fragment with cpp -P -std=c++11 filename to reproduce.

The trick behind #__VA_ARGS__ is that __VA_ARGS__ does not process the comma separator. So you can pass it to the stringizing operator. Leading and trailing spaces are trimmed, and spaces (including newlines) between words are compressed to a single space then. Parentheses need to be balanced. I think these shortcomings explain why the designers of C++11, despite #__VA_ARGS__, saw the need for raw string literals.

Solution 9 - C++

// C++11. 
std::string index_html=R"html(
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>VIPSDK MONITOR</title>
    <meta http-equiv="refresh" content="10">
</head>
<style type="text/css">
</style>
</html>
)html";

Solution 10 - C++

Option 1. Using boost library, you can declare the string as below

const boost::string_view helpText = "This is very long help text.\n"
      "Also more text is here\n"
      "And here\n"

// Pass help text here
setHelpText(helpText);

Option 2. If boost is not available in your project, you can use std::string_view() in modern C++.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionrlbondView Question on Stackoverflow
Solution 1 - C++unwindView Answer on Stackoverflow
Solution 2 - C++emsrView Answer on Stackoverflow
Solution 3 - C++Raydelto HernandezView Answer on Stackoverflow
Solution 4 - C++Zlatan StanojevićView Answer on Stackoverflow
Solution 5 - C++bcmpincView Answer on Stackoverflow
Solution 6 - C++EricView Answer on Stackoverflow
Solution 7 - C++CXJView Answer on Stackoverflow
Solution 8 - C++Andreas SpindlerView Answer on Stackoverflow
Solution 9 - C++user3635122View Answer on Stackoverflow
Solution 10 - C++piyu2coolView Answer on Stackoverflow