将C++字符串拆分成多行(代码语法,不是解析)

88

请注意,这与如何按解析方式分割字符串不要混淆,例如:
在C++中分割字符串?

我有些困惑如何在C++中将一个字符串分成多行。

这听起来像一个简单的问题,但看下面的例子:

#include <iostream>
#include <string>
main() {
  //Gives error
  std::string my_val ="Hello world, this is an overly long string to have" +
    " on just one line";
  std::cout << "My Val is : " << my_val << std::endl;

  //Gives error
  std::string my_val ="Hello world, this is an overly long string to have" &
    " on just one line";  
  std::cout << "My Val is : " << my_val << std::endl;
}

我知道我可以使用std::stringappend()方法,但我想知道是否有更短/更优雅的(例如更像Python的)方式在C++中将字符串分成多行以增加可读性(显然C++不支持三重引号等)。

这种情况特别希望的一个地方是当您将长字符串字面量传递给函数时(例如一个句子)。


3
这里有一个有趣的小知识:C++词法分析器实际上并不关心您在字符串前后放置了多少引号,只有两个例外。您使用的引号数必须是奇数,并且它们必须在两侧匹配。""""" 这是一个有效的字符串,将被解析 """""。但是,这些字符串没有特殊属性,它们只是像单引号一样运作。 - Thomas Anthony
有趣,感谢分享...那有什么有用的目的吗?你可以将其用作代码中不同字符串组的微妙标记,以供perl/bash/python脚本进行外部解析。这就是我现在能想到的全部。 :) - Jason R. Mick
1
@ThomasAnthony 这只是因为它将把最后的引号视为一堆空字符串并将它们链接在一起,这不是一个功能,而是标准的C/C++行为。 - texasflood
3个回答

151
不要在字符串之间放置任何东西。 C++ 词法分析阶段的一部分是将相邻的字符串字面量(甚至跨越换行符和注释)组合为单个字面量。
#include <iostream>
#include <string>
main() {
  std::string my_val ="Hello world, this is an overly long string to have" 
    " on just one line";
  std::cout << "My Val is : " << my_val << std::endl;
}

请注意,如果您想在文本中添加换行符,您需要自己添加:

#include <iostream>
#include <string>
main() {
  std::string my_val ="This string gets displayed over\n" 
    "two lines when sent to cout.";
  std::cout << "My Val is : " << my_val << std::endl;
}

如果你想将一个#define的整数常量混合到字面值中,你需要使用一些宏:

#include <iostream>
using namespace std;

#define TWO 2
#define XSTRINGIFY(s) #s
#define STRINGIFY(s) XSTRINGIFY(s)

int main(int argc, char* argv[])
{
    std::cout << "abc"   // Outputs "abc2DEF"
        STRINGIFY(TWO)
        "DEF" << endl;
    std::cout << "abc"   // Outputs "abcTWODEF"
        XSTRINGIFY(TWO) 
        "DEF" << endl;
}

由于 stringify 处理器操作符的工作方式有些奇怪,所以在这里存在一些混乱,因此您需要两个宏级别才能将实际值 TWO 转换为字符串文字。


你可以混合其他项,如整数常量吗?如果不能,那么我应该如何添加它们? - Jason R. Mick
@Jason:你说的"mixing in an int constant"是什么意思? - Eclipse
在“TWO”和“两行长”的之间换行。 - Jason R. Mick
4
将字符串字面量组合起来是词法分析阶段的一部分(而非预处理器的一部分),因为像这样的字符串拆分被定义为语言的一部分。 - Martin York
1
@Jason,从你的后续问题来看,似乎你需要类似上面STRINGIFY宏的东西。 - Eclipse
显示剩余2条评论

11

它们都是字面值吗?用空格分隔两个字符串字面值等同于连接操作:"abc" "123" 等同于 "abc123"。这适用于纯 C 和 C++。


8

我不确定这是GCC扩展还是标准,但似乎你可以通过在字符串字面值末尾用反斜杠结束一行来继续一个字符串字面值(就像C ++中大多数类型的行可以使用此方法扩展,例如跨越多行的宏)。

#include <iostream>
#include <string>

int main ()
{
    std::string str = "hello world\
    this seems to work";

    std::cout << str;
    return 0;
}

7
字面语法中worldthis之间包含相当多的空格。 - SingleNegationElimination
1
@TokenMacGuy: 的确如此,我之前没有注意到。如果您将第二行(以及后续行)全部移到最左边,则很容易修复。但这将真正影响您的缩进外观。 - rmeador
是的,那是我的最初方法,但由于@SingleNegationElimination指出的缩进/空格问题,我放弃了它。不过这个要注意。 - Jason R. Mick

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接