代码之家  ›  专栏  ›  技术社区  ›  rlbond

C++多行字符串文字

  •  347
  • rlbond  · 技术社区  · 17 年前

    有什么方法可以让多行纯文本、C++中的常数文字、?也许是一些解析技巧 #include 一个文件?我想不出一个,但是孩子,那太好了。我知道它将在C++0X中。

    7 回复  |  直到 9 年前
        1
  •  505
  •   unwind    9 年前

    好。。。某种程度上。最简单的方法是使用编译器连接相邻字符串的事实:

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

    同样,注意每行末尾的反斜杠,它们必须在行尾之前,它们正在从源代码中转义换行符,以便所有的操作都像换行符不在那里一样。在反斜杠所在的位置,字符串中没有换行符。使用此表单,显然无法缩进文本,因为缩进将成为字符串的一部分,并将其与随机空格混淆。

        2
  •  301
  •   Drew Dormann    9 年前

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

    引号内的parens仍然是必需的。

        3
  •  25
  •   Zlatan Stanojević    13 年前

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

        4
  •  23
  •   bcmpinc    12 年前

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

    #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__ 允许使用 , .

        5
  •  12
  •   Eric    13 年前

    你可以这样做:

    const char *text = "This is my string it is "
         "very long";
    
        6
  •  9
  •   Andreas Spindler    12 年前

    因为一点经验值很多理论,我尝试了一个小测试程序 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的设计者,尽管 V.A.AgsSuz ,发现需要原始字符串文本。

        7
  •  7
  •   CXJ    13 年前

    只是为了在@ unSune的回答中解释一下@ 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的简短评论在我第一次读到这篇文章时并没有跳出来,所以我必须自己去发现。希望,我已经救了别人几分钟了。