【问题标题】:What is the proper format of writing raw strings with '$' in C++?在 C++ 中用“$”编写原始字符串的正确格式是什么?
【发布时间】:2021-02-27 16:54:43
【问题描述】:

我正在通过cplusplus.com tutorial on constants 了解 C++ 中的原始字符串。根据该站点上的定义,原始字符串应以R"sequence( 开头并以)sequence 结尾,其中sequence 可以是任何字符序列。

该网站的一个例子如下:

R"&%$(string with \backslash)&%$"

但是,当我尝试编译包含上述原始字符串的代码时,出现编译错误。

test.cpp:5:28: error: invalid character '$' in raw string delimiter
    5 |     std::string str = R"&%$(string with \backslash)&%$";
      |                       ^
test.cpp:5:23: error: stray 'R' in program

我在 Windows 和 Linux 上都使用 g++ 和 clang++ 进行了尝试。他们都没有工作。

【问题讨论】:

  • 引用cppreference:“由任何源字符组成的字符序列,但括号、反斜杠和空格”(强调我的)。但是basic source character set 不包含$ 字符,这就是原因。
  • @drescherjm 也许是因为$ 没有用于任何语言功能?在我看来,基本集合需要能够表示关键字、数字、运算符和其他内置 C++ 语言功能。另一方面,$@ 等。只是“为了好玩”。 ;)
  • “网站示例之一”cplusplus.com 再次来袭。最好假装这个网站不存在。
  • 我误解了不能使用$ 的地方。我现在明白了。
  • @NicolBolas - 如果 Google 没有几乎总是在结果中将 cplusplus.com 放在 cppreference.com 之上...

标签: c++ string


【解决方案1】:

来自C++ reference

分隔符:由任何源字符组成的字符序列,但括号、反斜杠和空格除外(可以为空,最多 16 个字符)

请注意此处的“任何源字符”部分。

让我们看看标准是怎么说的:

来自[gram.lex]

原始字符串
"d-char-sequenceopt(r-char-sequenceopt)d-char-sequence选择"

...

d-char-sequence:
d-char
d-char-sequence d-char

d-char:
基本源字符集的任何成员,除了:空格、左括号(、右括号)、反斜杠\,以及表示水平制表符、垂直制表符、换页符和换行符的控制字符。

那么,什么是基本的源字符集?来自[lex.charset]

基本源字符集由 96 个字符组成:空格字符、代表水平制表符、垂直制表符、换页符和换行符的控制字符,以及以下 91 个图形字符:

a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 0 1 2 3 4 5 6 7 8 9_ { } [ ] # ( ) % : ; . ? * + - / ^ & |~! = , \" '

...不包括$;所以结论是美元符号$不能成为分隔符序列的一部分。

【讨论】:

  • @AntoninGAVREL 也许在过去没有$ 符号的键盘布局/编码?我不太确定。
  • @AntoninGAVREL:有什么要解决的?只是不要尝试在这里使用它。没有特别的理由。
  • @drescherjm 它不排除 $ 从文字的主体,只是分隔符。几乎总是,您可以从(超过)88 ^ 16 组合中找到一个非常好的分隔符。
  • 简而言之:使用 cppreference.com,而不是 cplusplus.com。后者往往有更多这样的不准确之处,浪费的时间越来越多。
【解决方案2】:

对于基本源字符集,请参阅lex.charset 5.3 (1):该集不包含$ 字符。对于原始字符串文字中允许的前缀字符,请参阅 lex.string 5.13.5: "/.../ 基本源字符集的任何成员,除了:空格、左括号 (、右括号括号),反斜杠\,以及代表水平制表符、垂直制表符、换页符和换行符的控制字符。”(强调我的)。

【讨论】:

    【解决方案3】:

    只需像下面的代码一样删除$

    string string3 = R"&%(string with \backslash)&%";
    

    $ 给出错误,因为基本源字符集没有 $,如 cmets 中所述。

    1. 源代码文件的各个字节被映射(以实现定义的方式)到基本源字符集的字符。特别是,依赖于操作系统的行尾指示符被换行符替换。基本源字符集由 96 个字符组成:

    a) 5 个空白字符(空格、水平制表符、垂直制表符、换页符、换行符)

    b) '0' 到 '9' 的 10 位数字字符

    c) 从 'a' 到 'z' 和从 'A' 到 'Z' 的 52 个字母

    d) 29 个标点符号:_ { } [ ] # ( ) % : ; . ? * + - / ^ & | ~ ! = , \" ' 2) 任何无法映射到基本源字符集中字符的源文件字符都将替换为其通用字符名称(用 \u 或 \U 转义)或等效处理的某些实现定义的形式。

    参考:Click here

    【讨论】:

      猜你喜欢
      • 2018-02-10
      • 2019-11-04
      • 1970-01-01
      • 1970-01-01
      • 2013-05-13
      • 2022-11-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多