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

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

string script = " Some Formatted String Literal "; 

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

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

 string script = """ Some Formatted String Literal """; 

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

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

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

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

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

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

 const char* script = "\ Some\n\ Formatted\n\ String Literal\n\ "; 

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

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

 const char* script = " Some\n" " Formatted\n" " String Literal\n"; 

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

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

 const char* script = " Some\n Formatted\n String Literal\n"; 

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

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

C预处理器逐行工作,但使用词法标记。 这意味着预处理器理解"foo"是一个标记。 但是,如果C允许多行文字,那么预处理器就会遇到麻烦。 考虑:

 "foo #ifdef BAR bar #endif baz" 

预处理器无法弄乱令牌内部 – 但它是逐行操作的。 那怎么处理这个案子呢? 简单的解决方案是完全禁止多行字符串。

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

 #include  #include  int main() { std::string str = R"(a b)"; std::cout << str; } /* Output: a b */ 

现场演示。


[n3290: 2.14.5/4]: [ 注意:原始字符串文字中的源文件换行会在生成的执行字符串文字中产生换行符。 假设在以下示例中的行的开头没有空格,则断言将成功:

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

- 尾注 ]

虽然非规范性,但本说明及其在[n3290: 2.14.5/5]的示例用于补充语法中的指示,即生产r-char-sequence可能包含换行符(而生成s-char-sequence ,用于普通字符串文字,可能不会)。

实际上,你可以分解它:

 string script = "\n" " Some\n" " Formatted\n" " String Literal\n"; 

相邻的字符串文字由编译器连接。

字符串可以放在多行上,但每行必须单独引用:

 string script = " \n" " Some \n" " Formatted \n" " String Literal "; 

我正在编写一种编程语言(类似于C),并希望轻松编写多行字符串(如上例所示)。

没有理由不能创建允许多行字符串的编程语言。 例如, Vedit Macro Language (VEDIT文本编辑器的类C脚本语言)允许使用多行字符串,例如:

 Reg_Set(1," Some Formatted String Literal ") 

您可以自行决定如何定义语言语法。

你也可以这样做:

 string useMultiple = "this" "is " "a string in C."; 

将一个文字放在另一个字面上,没有任何特殊的字符。

文字声明不一定是单行的。

GPUImage内联多行着色器代码。 签出它的SHADER_STRING宏。