C++ 多行字符串文字

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1135841/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 18:58:16  来源:igfitidea点击:

C++ multiline string literal

c++string-literals

提问by rlbond

Is there any way to have multi-line plain-text, constant literals in C++, à la Perl? Maybe some parsing trick with #includeing a file? I can't think of one, but boy, that would be nice. I know it'll be in C++0x.

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

回答by unwind

Well ... Sort of. The easiest is to just use the fact that adjacent string literals are concatenated by the compiler:

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

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

The indentation doesn't matter, since it's not inside the quotes.

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

You can also do this, as long as you take care to escape the embedded newline. Failure to do so, like my first answer did, will not compile:

您也可以这样做,只要您小心转义嵌入的换行符即可。如果不这样做,就像我的第一个答案一样,将无法编译:

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

Again, note those backslashes at the end of each line, they must be immediately before the line ends, they are escaping the newline in the source, so that everything acts as if the newline wasn't there. You don't get newlines in the string at the locations where you had backslashes. With this form, you obviously can't indent the text since the indentation would then become part of the string, garbling it with random spaces.

再次注意每行末尾的那些反斜杠,它们必须紧接在行结束之前,它们在源代码中转义换行符,因此一切都好像换行符不存在一样。在有反斜杠的位置,您不会在字符串中获得换行符。使用这种形式,您显然无法缩进文本,因为缩进将成为字符串的一部分,并用随机空格将其弄乱。

回答by emsr

In C++11 you have raw string literals. Sort of like here-text in shells and script languages like Python and Perl and Ruby.

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

All the spaces and indentation and the newlines in the string are preserved.

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

These can also be utf-8|16|32 or wchar_t (with the usual prefixes).

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

I should point out that the escape sequence, V0G0N, is not actually needed here. Its presence would allow putting )" inside the string. In other words, I could have put

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

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

(note extra quotes) and the string above would still be correct. Otherwise I could just as well have used

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

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

The parens just inside the quotes are still needed.

仍然需要引号内的括号。

回答by Zlatan Stanojevi?

#define MULTILINE(...) #__VA_ARGS__
Consumes everything between the parentheses.
Replaces any number of consecutive whitespace characters by a single space.

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

回答by bcmpinc

A probably convenient way to enter multi-line strings is by using macro's. This only works if quotes and parentheses are balanced and it does not contain 'top level' comma's:

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

#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);

Compiled with gcc 4.6 or g++ 4.6, this produces: [[Using this trick(,) you don't need to use quotes. Though newlines and multiple white spaces will be replaced by a single whitespace.]]

用 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.]]

Note that the ,cannot be in the string, unless it is contained within parenthesis or quotes. Single quotes is possible, but creates compiler warnings.

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

Edit:As mentioned in the comments, #define MULTI_LINE_STRING(...) #__VA_ARGS__allows the use of ,.

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

回答by Raydelto Hernandez

You can also do this:

你也可以这样做:

const char *longString = R""""(
This is 
a very 
long 
string
)"""";

回答by Eric

You can just do this:

你可以这样做:

const char *text = "This is my string it is "
     "very long";

回答by Andreas Spindler

Since an ounce of experience is worth a ton of theory, I tried a little test program for MULTILINE:

由于一盎司的经验值得大量的理论,我尝试了一个小测试程序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" )      // "1, \"2\" "
};

Compile this fragment with cpp -P -std=c++11 filenameto reproduce.

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

The trick behind #__VA_ARGS__is that __VA_ARGS__does not process the comma separator. So you can pass it to the stringizing operator. Leading and trailing spaces are trimmed, and spaces (including newlines) between words are compressed to a single space then. Parentheses need to be balanced. I think these shortcomings explain why the designers of C++11, despite #__VA_ARGS__, saw the need for raw string literals.

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

回答by CXJ

Just to elucidate a bit on @emsr's comment in @unwind's answer, if one is not fortunate enough to have a C++11 compiler (say GCC 4.2.1), and one wants to embed the newlines in the string (either char * or class string), one can write something like this:

只是为了在@unwind 的回答中阐明@emsr 的评论,如果一个人没有幸运地拥有 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.";

Very obvious, true, but @emsr's short comment didn't jump out at me when I read this the first time, so I had to discover this for myself. Hopefully, I've saved someone else a few minutes.

很明显,没错,但是当我第一次读到这篇文章时,@emsr 的简短评论并没有引起我的注意,所以我必须自己发现这一点。希望我已经为其他人节省了几分钟。

回答by user3635122

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

回答by piyu2cool

Option 1. Using boost library, you can declare the string as below

选项 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);

Option 2. If boost is not available in your project, you can use std::string_view() in modern C++.

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