在未终止的原始字符串字面量中包含 ")"。

50
下面的示例中,两个字符)"终止了原始字符串文字。序列)"可能会在我的文本中出现,在其中找到这个序列时,我希望字符串继续而不是停止。
R"(  
    Some Text)"  
)";       // ^^

如何在字符串字面量中包含序列)"而不终止它?

3个回答

84

原始字符串字面值 允许您指定一个几乎任意的分隔符:

//choose ### as the delimiter so only )###" ends the string
R"###(  
    Some Text)"  
)###";  

具体规则如下: "基本源字符集中的任何成员,除了空格、左圆括号( 、右圆括号 )、反斜杠\和表示水平制表符、垂直制表符、换页符和换行符的控制字符" (N3936 §2.14.5 [lex.string]语法) 以及 "最多16个字符" (§2.14.5/2)



31

转义并不能帮助你,因为这是一个原始文本,但语法的设计允许通过引入一些任意短语(例如aha)来清晰地标记开始和结束。

R"aha(  
    Some Text)"  
)aha";

顺便提一下,注意括号)和引号"的顺序是相反的,与你的示例相反。


关于正式的规范,在第一眼看上去(研究标准时)它似乎在原始字符串字面值中也像普通字面值中一样工作。除非有人知道它不是这样的,那么这是如何可能的呢?当然,在规则中没有注明任何异常的情况下?好吧,当原始字符串字面值在C++11中被引入时,是通过引入一个额外的撤销转换阶段来实现的,以撤销例如转义的效果! 具体来说,…

C++11 §2.5/3

在原始字符串的初始和最终双引号字符之间,对于阶段1和阶段2中执行的任何转换(三字符组,通用字符名称和行分隔符),都将被还原;在识别出任何d-charr-char或定界圆括号之前,应用此还原。

这解决了Unicode字符规范(类似于\u0042通用字符名称),尽管它们看起来和表现得像是转义,但在C++中,它们在形式上不是转义序列。

真正的正式转义由使用原始字符串字面值内容的自定义语法规则处理,或者更确切地说,没有处理!换句话说,在C++ §2.14.5中将raw-string语法实体定义为:

" d-char-sequenceopt ( r-char-sequenceopt ) d-char-sequenceopt "

其中r-char-sequence被定义为一系列r-char,每个r-char都是

源字符集的任何成员,除了紧随其后的右括号),后跟初始d-char-sequence[例如上面的aha](可以为空),后跟双引号"


以上基本意味着你不仅不能直接在原始字符串中使用转义(这就是重点,它是积极的,而不是消极的),而且你也不能直接使用Unicode字符规范。

以下是间接用法:

#include <iostream>
using namespace std;

auto main() -> int
{
    cout << "Ordinary string with a '\u0042' character.\n";
    cout << R"(Raw string without a '\u0042' character, and no \n either.)" "\n";
    cout << R"(Raw string without a '\u0042' character, i.e. no ')" "\u0042" R"(' character.)" "\n";
}

输出:

带有字符'B'的普通字符串。
没有'\u0042'字符和换行符的原始字符串。
没有'\u0042'字符,即没有'B'字符的原始字符串。

3
您可以使用:
R"aaa(  
    Some Text)"  
)aaa"; 

这里的aaa将是您的字符串分隔符。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接