什么是原始字符串?

What is a raw string?

本文关键字:字符串 原始 什么      更新时间:2023-10-16

我在 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++的转义字符(如nt")。以R"(开头并以)"结尾的原始字符串文本,在C++11中引入

前缀(可选) R "分隔符( raw_characters )分隔符">

前缀 - L, u8, u, U 之一

感谢@Remy勒博,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;
}

输出:

第一行。

第二行。

消息结束。

第一行。第二行。消息结束。

"(第一行。第二行...">

住在戈博尔特上

我将在其中一条评论中对一个问题进行补充:

但是在代码中,R 被定义为"x",之后 代码 #define 的扩展是常量字符* s = "x"y"; 并且没有任何 R"(.

问题中的代码片段显示原始字符串的无效用法。让我在这里获得实际的 3 行代码:

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

不同之处在于,原始字符串忽略(转义)所有特殊字符,如 ant \t,并像普通文本一样威胁它们。

因此,上面的行只是一行,其中包含 3 个实际的 ,而不是 3 个单独的行。

您需要删除定义行并在字符串周围添加括号以被视为原始字符串。