有什么方法可以在C ++中使用Perl编写多行纯文本,常量文字?也许解析#include
文件有一些技巧?我想不出一个,但是男孩,那太好了。我知道它将用C ++ 0x。
有什么方法可以在C ++中使用Perl编写多行纯文本,常量文字?也许解析#include
文件有一些技巧?我想不出一个,但是男孩,那太好了。我知道它将用C ++ 0x。
Answers:
好吧。最简单的方法是使用以下事实:相邻字符串文字由编译器连接:
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 = “另一方面,我疯了\ 并真正让文字跨越几行, 不用麻烦引用每一行的\ 内容。这可行,但是您不能缩进。”
同样,请注意每行末尾的那些反斜杠,它们必须紧接在行末之前,它们在源代码中转义了换行符,以便所有内容都好像换行符不在那里。在反斜杠的位置,字符串中不会出现换行符。使用这种形式,您显然无法缩进文本,因为缩进将随后成为字符串的一部分,并在字符串中添加随机空格。
在C ++ 11中,您具有原始字符串文字。shell和脚本语言(例如Python,Perl和Ruby)中的此处文本有点类似。
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
注释掉代码块即可。也筑巢。
#define MULTILINE(...) #__VA_ARGS__
消耗括号之间的所有内容。
用单个空格替换任意数量的连续空格字符。
\n
如果需要换行,可以添加
` (and hence
\ n ) is copied literally, but
“`转换成\"
左右。MULTILINE(1, "2" \3)
产量"1, \"2\" \3"
。
输入多行字符串的一种可能方便的方法是使用宏。仅当引号和括号之间是平衡的并且不包含“顶级”逗号时,此方法才有效:
#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__
允许使用,
。
#define MULTILINE(...) #__VA_ARGS__
如果希望字符串包含逗号,则可以使用。
\n
和\r
),这在某些情况下是很方便的,而在另一些情况下是致命的。
您也可以这样做:
const char *longString = R""""(
This is
a very
long
string
)"""";
char longString[] = R""""( This is a very long string )"""";
,对我来说也是如此。
由于一盎司的经验值得大量理论研究,因此我尝试了以下测试程序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__
看到了对原始字符串文字的需求。
只是为了阐明@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的简短评论并没有引起我的注意,因此我必须自己发现这一点。希望我已经节省了别人几分钟。