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

时间:2010-06-22 13:40:12

标签: c++ c programming-languages string language-design

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

string script =
"
      Some
   Formatted
 String Literal
";

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

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

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

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

10 个答案:

答案 0 :(得分:31)

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

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

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

答案 1 :(得分:14)

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

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

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

答案 2 :(得分:6)

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

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

答案 3 :(得分:4)

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

"foo
#ifdef BAR
bar
#endif
baz"

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

答案 4 :(得分:4)

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

#include <iostream>
#include <string>

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

/* Output:
a
b
*/

Live demo.


  

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

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

-end note ]

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

答案 5 :(得分:2)

实际上,你可以分手:

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

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

答案 6 :(得分:1)

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

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

答案 7 :(得分:1)

  

我正在编写一种编程语言   (类似于C)并且想让   轻松编写多行字符串(如   在上面的例子中。)

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

Reg_Set(1,"
      Some
   Formatted
 String Literal
")

由您决定语言语法的定义。

答案 8 :(得分:0)

你也可以这样做:

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

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

答案 9 :(得分:0)

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

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