我在C++17草案n4713中发现了这段代码片段:
#define R "x"
const char* s = R"y"; // ill-formed raw string, not "x" "y"
"原始字符串"是什么?它有什么作用?
原始字符串字面量是用于简化包含有特殊含义的定界符和转义序列起始字符,例如引号和反斜杠等嵌套字符的字符串字面量。它们可用于编码HTML文本等场景。例如,与之相比:
"<a href=\"file\">C:\\Program Files\\</a>"
这是一个常规的字符串文字,附带
R"(<a href="file">C:\Program Files\</a>)"
这是一个原始字符串字面量。在这里,除了引号之外使用括号可以使C ++区分嵌套的引号和限定字符串本身的引号。
基本上,原始字符串字面值是指C++中的转义字符(如\n
\t
或\"
)未被处理的字符串。引入于C++11
的原始字符串字面值以R"(
开头并以)"
结尾。
前缀(可选)R "定界符(原始字符)定界符"
前缀- L、u8、u、U之一
感谢@Remy Lebeau,
delimiter
是可选的,通常省略,但在某些特殊情况下实际上是需要的,特别是如果字符串内容包含)"
这个字符序列,例如:R"(...)"...)"
,那么您需要一个定界符来避免错误,例如:R"x(...)"...)x"
。
以下是一个示例:
#include <iostream>
#include <string>
int main()
{
std::string normal_str = "First line.\nSecond line.\nEnd of message.\n";
std::string raw_str = R"(First line.\nSecond line.\nEnd of message.\n)";
std::string raw_str_delim = R"x("(First line.\nSecond line...)")x";
std::cout << normal_str << std::endl;
std::cout << raw_str << std::endl;
std::cout << raw_str_delim << std::endl;
return 0;
}
输出:
第一行。
第二行。
消息结束。
第一行。\n第二行。\n消息结束。\n
"(第一行。\n第二行...)"
在Godbolt上实时运行
R
被定义为"x"
,在#define
扩展后,代码变成了const char* s = "x""y";
,并且没有任何R"(
。 - Chupo_cro我将对评论中的一个问题进行補充:
但是这里代码中的 R 被定义为 "x",在 #define 展开之后,代码变成了 const char* s = "x""y";并且没有任何 R"(。
问题中的代码片段是为了展示 Raw Strings 的无效用法。让我在此提供实际的三行代码:
#define R "x"
const char* s = R"y"; // ill-formed raw string literal, not "x" "y"
const char* s2 = R"(a)" "b)"; // a raw string literal followed by a normal string literal
R"(x)"
,其中需要在括号内包含字符串。R"_(a)" "b)_ "
。下划线可以替换为任何字符(但不能是括号、反斜杠和空格),并且可以是任意数量的字符,只要不包含结束序列:R"___(a)" "b)___"
或R"anything(a)" "b)anything"
因此,如果我们将这些更正包装在一个简单的C++代码中:
#include <iostream>
using namespace std;
#define R "x" // This is just a macro, not Raw String nor definition of it
const char* s = R"(y)"; // R is part of language, not a macro
const char* s2 = R"_(a)" "b)_"; // Raw String shall not include closing sequence of characters; )_"
int main(){ cout << s <<endl << s2 <<endl << R <<endl; }
y
a)" "b
x
原始字符串字面值。用于避免任何字符的转义。定界符之间的所有内容都成为字符串的一部分。如果有前缀,则具有与上述描述相同的含义。
C++参考:字符串字面值
原始字符串定义如下:
string raw_str=R"(First line.\nSecond line.\nEnd of message.\n)";
uR
和u8R
一样添加前缀,并且这也适用于 C,但仅适用于 gnu-std=gnu99
及以后的版本。 - Lewis Kelsey