为什么C/C++字符串文字声明必须是单行的?

Riz*_*izo 17 c c++ string programming-languages language-design

是否有任何特殊原因在C++中不允许使用以下多行字符串文字?

string script =
"
      Some
   Formatted
 String Literal
";
Run Code Online (Sandbox Code Playgroud)

我知道可以通过在每个换行符之前放一个反斜杠来创建多行字符串文字.我正在编写一种编程语言(类似于C),并希望能够轻松创建多行字符串(如上例所示).

是否有任何技术原因可以避免这种字符串文字?否则我将不得不使用类似python的字符串文字和三重引号(我不想这样做):

string script =
"""
      Some
   Formatted
 String Literal
""";
Run Code Online (Sandbox Code Playgroud)

为什么C/C++字符串文字声明必须是单行的?

Jam*_*lis 30

简洁的答案是"因为语法禁止多行字符串文字." 除了历史原因,我不知道这是否有充分的理由.

当然,有办法解决这个问题.您可以使用线拼接:

const char* script = "\
      Some\n\
   Formatted\n\
 String Literal\n\
";
Run Code Online (Sandbox Code Playgroud)

如果该行\显示为该行的最后一个字符,则在预处理期间将删除换行符.

或者,您可以使用字符串文字串联:

const char* script = 
"      Some\n"
"   Formatted\n"
" String Literal\n";
Run Code Online (Sandbox Code Playgroud)

在预处理期间连接相邻的字符串文字,因此这些文字在编译时最终将作为单个字符串文字.

使用任何一种技术,字符串文字最终会像写入一样:

const char* script = "      Some\n   Formatted\n  String Literal\n";
Run Code Online (Sandbox Code Playgroud)

  • 始终使用第二种形式; 它适用于某些版本的Microsoft编译器中的长文字处理中的错误. (8认同)

NoM*_*ots 15

人们必须考虑到C不是编写为"应用程序"编程语言而是编写系统编程语言.说它是专门为改写Unix而设计的并不是不准确的.考虑到这一点,没有EMACS或VIM,您的用户界面是串行终端.在没有多行文本编辑器的系统上,多行字符串声明似乎有点无意义.对于那些在特定时间点编写操作系统的人来说,更多字符串操作不是主要关注点.传统的UNIX脚本工具集(例如AWK和SED(在许多其他人之中))证明了他们没有使用C来执行重要的字符串操作.

其他考虑因素,在70年代早期(编写C时)在PUNCH CARDS上提交您的程序并在第二天复出以获得它们并不罕见.是否已经耗费额外的处理时间来编译具有多行字符串文字的程序?实际上它对编译器来说实际上并不那么简单.但是在大多数情况下,无论如何你都会在第二天复出.但是,没有人填写一张穿孔卡会打算放入大量的程序中不需要的文本.

在现代环境中,除了设计者的偏好之外,可能没有理由不包括多行字符串文字.从字面上讲,它可能更简单,因为在解析字符串文字时不必考虑换行符.


Ran*_*pho 6

其他人提到了一些很好的解决方法,我只想解决其中的原因.

原因很简单,C是在处理非常宝贵的时候创建的,编译器必须尽可能简单和快速.这些天,如果要更新C(我正在看你,C1X),很有可能做到你想要的.但是,这不太可能.主要是出于历史原因; 这样的改变可能需要对编译器进行大量重写,因此可能会被拒绝.


Lig*_*ica 6

除了现有的答案,您还可以使用C ++ 11的原始字符串文字解决此问题,例如:

#include <iostream>
#include <string>

int main() {
   std::string str = R"(a
b)";
   std::cout << str;
}

/* Output:
a
b
*/
Run Code Online (Sandbox Code Playgroud)

现场演示。


[n3290: 2.14.5/4]:[ 注意:原始字符串文字中的源文件换行会在结果执行string-literal中产生换行 。在下面的示例中,假设行首没有空白,则断言将成功:

const char *p = R"(a\
b
c)";
assert(std::strcmp(p, "a\\\nb\nc") == 0);
Run Code Online (Sandbox Code Playgroud)

—尾注 ]

尽管不是规范性的,但是此注释及其后面的示例[n3290: 2.14.5/5]用于补充语法中表示生产r-char-sequence可能包含换行符的指示(而s-char-sequence用于普通字符串文字的生产可能不包含换行符)。