我知道在C++11中可以使用原始字符串来实现。
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.";
const char *text2 =
"Here, on the other hand, I've gone crazy \
and really let the literal span several lines, \
without bothering with quoting each line's \
content. This works, but you can't indent.";
C++11引入了原始字符串字面量,类似于Shell、Python、Perl和Ruby等脚本语言中的here-doc。
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"( ... )";
引号内部的括号仍然是必需的。
#if 0
… #endif
来注释掉代码块,嵌套也可以。 - bobbogo您也可以这样做:
const char *longString = R""""(
This is
a very
long
string
)"""";
char longString[] = R""""( This is a very long string )"""";
对我也适用。 - struggling_learner( ...)
时怎么办?我试图将其转换为 R
风格,这样就不需要 \"
等符号,但无法让它正常工作:L"<xsl:variable name=\"DutyHistory\" select=\"document('DutyAssignHistory.XML')\"/>"
。 - Andrew Truckle#define MULTILINE(...) #__VA_ARGS__
消费括号内的所有内容。
将任意数量连续的空格字符替换为单个空格。
\n
。 - Simon\
(因此也包括\n
)会被直接复制,但是"
会被转换为\"
。因此,MULTILINE(1, "2" \3)
将生成"1, \"2\" \3"
。 - Andreas Spindler使用宏的一种可能方便的方式是输入多行字符串。这仅在引号和括号平衡并且不包含“顶级”逗号时才有效:
#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编译,将会生成:[[ 使用此技巧,您无需使用引号。尽管换行和多个空格将被替换为单个空格。]]
请注意,
不能出现在字符串中,除非它包含在括号或引号中。单引号是可能的,但会创建编译器警告。
编辑:如评论中所述,#define MULTI_LINE_STRING(...) #__VA_ARGS__
允许使用,
。
#define MULTILINE(...) #__VA_ARGS__
。 - Simon\n
和\r
),这对某些情况可能很方便,但对其他情况可能是致命的。 - BCSconst char *text = "This is my string it is "
"very long";
仅对@emsr在@unwind的回答中的评论进行一些阐述,如果一个人没有足够幸运拥有C++11编译器(比如GCC 4.2.1),并且想要将换行符嵌入字符串(无论是char *还是string类),可以编写类似于以下代码:
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的简短评论第一次阅读时没有给我留下深刻印象,所以我不得不自己发现这一点。希望我能为其他人节省几分钟时间。
既然一盎司经验胜过吨的理论,我为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 文件名
编译此片段以进行复现。
#__VA_ARGS__
背后的技巧在于__VA_ARGS__
不会处理逗号分隔符。因此,您可以将其传递给字符串化运算符。前导和尾随空格被修剪,并且单词之间的空格(包括换行符)被压缩为一个空格。圆括号需要平衡。我认为这些缺点解释了为什么C++11的设计者们,尽管有了#__VA_ARGS__
,还看到了原始字符串字面量的需求。
// 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";
选项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()
。