Using raw string literals to avoid escaping characters
Strings may contain special characters, such as non-printable characters (newline, horizontal and vertical tab, and so on), string and character delimiters (double and single quotes), or arbitrary octal, hexadecimal, or Unicode values. These special characters are introduced with an escape sequence that starts with a backslash, followed by either the character (examples include '
and "
), its designated letter (examples include n
for a new line, t
for a horizontal tab), or its value (examples include octal 050, hexadecimal XF7, or Unicode U16F0). As a result, the backslash character itself has to be escaped with another backslash character. This leads to more complicated literal strings that can be hard to read.
To avoid escaping characters, C++11 introduced raw string literals that do not process escape sequences. In this recipe, you will learn how to use the various forms of raw string literals.
Getting ready
In this recipe, and throughout the rest of this book, I will use the s
suffix to define basic_string
literals. This was covered earlier in this chapter in the Creating cooked user-defined literals recipe.
How to do it...
To avoid escaping characters, define the string literals with one of the following forms:
R"( literal )"
as the default form:auto filename {R"(C:\Users\Marius\Documents\)"s}; auto pattern {R"((\w+)=(\d+)$)"s}; auto sqlselect { R"(SELECT * FROM Books WHERE Publisher='Packtpub' ORDER BY PubDate DESC)"s};
R"delimiter( literal )delimiter"
, wheredelimiter
is any sequence of characters excluding parentheses, backslash, and spaces, andliteral
is any sequence of characters with the limitation that it cannot include the closing sequence)delimiter"
. Here is an example with!!
as delimiter:auto text{ R"!!(This text contains both "( and )".)!!"s }; std::cout << text << '\n';
How it works...
When string literals are used, escapes are not processed, and the actual content of the string is written between the delimiter (in other words, what you see is what you get). The following example shows what appears as the same raw literal string; however, the second one still contains escaped characters. Since these are not processed in the case of string literals, they will be printed as they are in the output:
auto filename1 {R"(C:\Users\Marius\Documents\)"s};
auto filename2 {R"(C:\\Users\\Marius\\Documents\\)"s};
// prints C:\Users\Marius\Documents\
std::cout << filename1 << '\n';
// prints C:\\Users\\Marius\\Documents\\
std::cout << filename2 << '\n';
If the text has to contain the )"
sequence, then a different delimiter must be used, in the R"delimiter( literal )delimiter"
form. According to the standard, the possible characters in a delimiter can be as follows:
Any member of the basic source character set except: space, the left parenthesis (the right parenthesis ), the backslash \, and the control characters representing horizontal tab, vertical tab, form feed, and newline.
Raw string literals can be prefixed by one of L
, u8
, u
, and U
to indicate a wide, UTF-8, UTF-16, or UTF-32 string literal, respectively. The following are examples of such string literals:
auto t1{ LR"(text)" }; // const wchar_t*
auto t2{ u8R"(text)" }; // const char*
auto t3{ uR"(text)" }; // const char16_t*
auto t4{ UR"(text)" }; // const char32_t*
auto t5{ LR"(text)"s }; // wstring
auto t6{ u8R"(text)"s }; // string
auto t7{ uR"(text)"s }; // u16string
auto t8{ UR"(text)"s }; // u32string
Note that the presence of the suffix ""s
at the end of the string makes the compiler deduce the type as various string classes and not character arrays.
See also
- Creating cooked user-defined literals to learn how to create literals of user-defined types