簡體   English   中英

C++ 多行字符串文字

[英]C++ multiline string literal

有沒有辦法在 C++ 中使用多行純文本常量文字,如 Perl? 也許一些解析技巧與#include一個文件? 我想不出一個,但是男孩,那會很好。 我知道它會在 C++0x 中。

嗯......有點。 最簡單的方法是使用相鄰字符串文字由編譯器連接的事實:

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

仍然需要引號內的括號。

你也可以這樣做:

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

#define MULTILINE(...) #__VA_ARGS__
消耗括號之間的所有內容。
用一個空格替換任意數量的連續空白字符。

輸入多行字符串的一種可能方便的方法是使用宏。 這僅在引號和括號平衡且不包含“頂級”逗號時才有效:

#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.]] [[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__允許使用,

你可以這樣做:

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

只是為了在@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.";

很明顯,沒錯,但是當我第一次讀到這篇文章時,@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 filename編譯此片段以重現。

#__VA_ARGS__背后的#__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";

您可以使用 string a = "this is line 1" "this is line 2";

選項 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() 。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM