The raw string literals in C++11 are very nice, except that the obvious way to format them leads to a redundant newline \n
as the first character.
Consider this example:
some_code();
std::string text = R"(
This is the first line.
This is the second line.
This is the third line.
)";
more_code();
The obvious workaround seems so ugly:
some_code();
std::string text = R"(This is the first line.
This is the second line.
This is the third line.
)";
more_code();
Has anyone found an elegant solution to this?
You can get a pointer to the 2nd character - skipping the leading newline - by adding 1 to the const char*
to which the string literal is automatically converted:
some_code();
std::string text = 1 + R"(
This is the first line.
This is the second line.
This is the third line.
)";
more_code();
IMHO, the above is flawed in breaking with the indentation of the surrounding code. Some languages provide a built-in or library function that does something like:
That allows usage like:
some_code();
std::string text = unindent(R"(
This is the first line.
This is the second line.
This is the third line.
)");
more_code();
Writing such a function is relatively simple...
std::string unindent(const char* p)
{
std::string result;
if (*p == '\n') ++p;
const char* p_leading = p;
while (std::isspace(*p) && *p != '\n')
++p;
size_t leading_len = p - p_leading;
while (*p)
{
result += *p;
if (*p++ == '\n')
{
for (size_t i = 0; i < leading_len; ++i)
if (p[i] != p_leading[i])
goto dont_skip_leading;
p += leading_len;
}
dont_skip_leading: ;
}
return result;
}
(The slightly weird p_leading[i]
approach is intended to make life for people who use tabs and spaces no harder than they make it for themselves ;-P, as long as the lines start with the same sequence.)