497

有没有办法在 C++ 中使用多行纯文本、常量文字,就像 Perl 一样?也许一些解析#include文件的技巧?我想不出一个,但是男孩,那会很好。我知道它会在 C++0x 中。

4

10 回答 10

685

嗯......有点。最简单的方法是使用编译器连接相邻字符串文字的事实:

const char *text =
  "This text is pretty long, but will be "
  "concatenated into just a single string. "
  "The disadvantage is that you have to quote "
  "each part, and newlines must be literal as "
  "usual.";

缩进无关紧要,因为它不在引号内。

你也可以这样做,只要你小心避开嵌入的换行符。不这样做,就像我的第一个答案一样,将无法编译:

常量字符 *text2 =
  “在这里,另一方面,我已经疯了\
真的让文字跨越几行,\
无需费心引用每一行的 \
内容。这行得通,但你不能缩进。";

再次注意每行末尾的反斜杠,它们必须在行结束之前,它们正在转义源中的换行符,因此一切都好像换行符不存在一样。在有反斜杠的位置,字符串中不会出现换行符。使用这种形式,你显然不能缩进文本,因为缩进会成为字符串的一部分,用随机空格弄乱它。

于 2009-07-16T07:00:20.223 回答
519

在 C++11 中,您有原始字符串文字。有点像 shell 和脚本语言(如 Python、Perl 和 Ruby)中的 here-text。

const char * vogon_poem = R"V0G0N(
             O freddled gruntbuggly thy micturations are to me
                 As plured gabbleblochits on a lurgid bee.
              Groop, I implore thee my foonting turlingdromes.   
           And hooptiously drangle me with crinkly bindlewurdles,
Or I will rend thee in the gobberwarts with my blurlecruncheon, see if I don't.

                (by Prostetnic Vogon Jeltz; see p. 56/57)
)V0G0N";

保留字符串中的所有空格和缩进以及换行符。

这些也可以是 utf-8|16|32 或 wchar_t(带有通常的前缀)。

我应该指出,这里实际上不需要转义序列 V0G0N。它的存在将允许将 )" 放在字符串中。换句话说,我可以把

                "(by Prostetnic Vogon Jeltz; see p. 56/57)"

(注意额外的引号)并且上面的字符串仍然是正确的。否则我也可以使用

const char * vogon_poem = R"( ... )";

仍然需要引号内的括号。

于 2011-03-28T14:11:47.070 回答
40

你也可以这样做:

const char *longString = R""""(
This is 
a very 
long 
string
)"""";
于 2019-04-15T12:49:48.817 回答
30

#define MULTILINE(...) #__VA_ARGS__
使用括号之间的所有内容。
用一个空格替换任意数量的连续空白字符。

于 2013-01-12T13:08:46.833 回答
28

输入多行字符串的一种可能方便的方法是使用宏。这仅适用于引号和括号平衡且不包含“顶级”逗号的情况:

#define MULTI_LINE_STRING(a) #a
const char *text = MULTI_LINE_STRING(
  Using this trick(,) you don't need to use quotes.
  Though newlines and     multiple     white   spaces
  will be replaced by a single whitespace.
);
printf("[[%s]]\n",text);

使用 gcc 4.6 或 g++ 4.6 编译,生成:[[Using this trick(,) you don't need to use quotes. Though newlines and multiple white spaces will be replaced by a single whitespace.]]

请注意,,不能在字符串中,除非它包含在括号或引号中。单引号是可能的,但会产生编译器警告。

编辑:如评论中所述,#define MULTI_LINE_STRING(...) #__VA_ARGS__允许使用,.

于 2012-04-03T18:21:42.513 回答
18

你可以这样做:

const char *text = "This is my string it is "
     "very long";
于 2009-07-16T06:58:14.580 回答
13

只是为了阐明@emsr 在@unwind 的答案中的评论,如果一个人没有足够的运气拥有一个 C++11 编译器(比如 GCC 4.2.1),并且想在字符串中嵌入换行符(char *或类字符串),可以这样写:

const char *text =
  "This text is pretty long, but will be\n"
  "concatenated into just a single string.\n"
  "The disadvantage is that you have to quote\n"
  "each part, and newlines must be literal as\n"
  "usual.";

很明显,是的,但@emsr 的简短评论在我第一次阅读时并没有让我跳出来,所以我必须自己发现这一点。希望我已经救了别人几分钟。

于 2013-01-15T22:01:24.947 回答
11

由于一盎司的经验值得大量的理论,我尝试了一个小测试程序MULTILINE

#define MULTILINE(...) #__VA_ARGS__

const char *mstr[] =
{
    MULTILINE(1, 2, 3),       // "1, 2, 3"
    MULTILINE(1,2,3),         // "1,2,3"
    MULTILINE(1 , 2 , 3),     // "1 , 2 , 3"
    MULTILINE( 1 , 2 , 3 ),   // "1 , 2 , 3"
    MULTILINE((1,  2,  3)),   // "(1,  2,  3)"
    MULTILINE(1
              2
              3),             // "1 2 3"
    MULTILINE(1\n2\n3\n),     // "1\n2\n3\n"
    MULTILINE(1\n
              2\n
              3\n),           // "1\n 2\n 3\n"
    MULTILINE(1, "2" \3)      // "1, \"2\" \3"
};

编译此片段cpp -P -std=c++11 filename以重现。

背后的技巧#__VA_ARGS____VA_ARGS__不处理逗号分隔符。因此,您可以将其传递给字符串化运算符。前导和尾随空格被修剪,然后单词之间的空格(包括换行符)被压缩为一个空格。括号需要平衡。我认为这些缺点解释了为什么 C++11 的设计者#__VA_ARGS__看到了对原始字符串文字的需求。

于 2013-09-11T13:14:26.123 回答
7
// C++11. 
std::string index_html=R"html(
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>VIPSDK MONITOR</title>
    <meta http-equiv="refresh" content="10">
</head>
<style type="text/css">
</style>
</html>
)html";
于 2020-01-08T03:20:10.103 回答
-4

选项 1. 使用 boost 库,您可以如下声明字符串

const boost::string_view helpText = "This is very long help text.\n"
      "Also more text is here\n"
      "And here\n"

// Pass help text here
setHelpText(helpText);

选项 2。如果您的项目中没有 boost 可用,您可以在现代 C++ 中使用 std::string_view() 。

于 2020-01-16T20:39:02.843 回答