C++ 字符串拼接

在实际开发中,我们经常需要把多段零散的文字连接成完整的一句话。在 C++ 中,拼接 std::string 字符串常用的有 3 种方式:① 使用 + 运算符;② 使用 += 运算符;③ 使用 append() 函数。

此外,如果需要把字符串和整数、浮点数拼在一起,还可以配合 std::to_string() 函数来实现。

使用 + 运算符

如果我们希望把两段或多段文本连接起来生成一个新的字符串,同时保留原来的字符串变量不变,最直观的做法就是使用加号(+)运算符。

语法:

std::string 新字符串 = 字符串1 + 字符串2;

说明:

当 + 运算符用于字符串时,它会将前后两段内容首尾连接起来,并返回拼接后的新字符串。参与拼接的既可以是 std::string 变量,也可以是双引号字符串字面量或单引号 char 字符。

示例 1:使用 + 拼接多个字符串

#include <iostream>
#include <string>

int main() {
    std::string first = "Hello";
    std::string second = "lvyenet";

    std::string result = first + " " + second;

    std::cout << result << '\n';
    std::cout << first << '\n';
    return 0;
}

运行结果如下。

Hello lvyenet
Hello

分析:

在这个例子中,first + " " + second 按从左往右的顺序把 3 段内容连成 "Hello lvyenet" 并赋给 result。从第二行输出可以看出,first 依然是 "Hello",说明 + 不会修改原变量。

使用 + 运算符拼接字符串时,有一个初学者很容易踩的坑:两个双引号字符串字面量,不能直接使用 + 相加。下面我们来对比一下正确与错误的写法:

std::string first = "lvye";

// 正确方式
std::string text1 = first + "net";
std::string text2 = first + " " + "net";

// 错误方式
std::string wrong1 = "lvye" + "net";
std::string wrong2 = "Hello " + "lvye" + first;

为什么 "lvye" + "net" 会报错呢?因为使用双引号直接写出来的字面量,在底层属于 C 风格字符串,也就是 char 字符数组,而不是 std::string 类型。C++ 不支持把两个字符数组直接使用 + 相加。

对于这一点,小伙伴们只需要记住一个规则:每一个 + 号的左右两边,至少要有一边是 std::string 类型。

由于 + 按从左往右计算,first + " " + "net" 会先算 first + " " 得到 std::string,再加 "net" 就完全合法。反过来写 "Hello " + "lvye" + first,第一步算两个字面量相加就会直接报错。

使用 += 运算符(推荐)

很多时候,我们并不需要生成新的字符串变量,而是手里已经有一个 std::string 变量,希望直接在它的末尾继续追加内容。遇到这种情况,使用 += 运算符会更加简单直接。

语法:

字符串变量 += 追加内容;

说明:

+= 会直接把右边的内容追加到左边字符串变量的末尾,原有的字符串变量会被直接修改。等号右边既可以是另一个 std::string 变量、双引号字符串字面量,也可以是单个 char 字符。

示例 2:使用 += 追加内容

#include <iostream>
#include <string>

int main() {
    std::string text = "C++";
    text += " Tutorial";
    text += '!';

    std::cout << text << '\n';
    return 0;
}

运行结果如下。

C++ Tutorial!

分析:

text 一开始保存的是 "C++"。执行 text += " Tutorial"; 后末尾被追加上 " Tutorial",接着再执行 text += '!'; 追加感叹号字符,最终 text 就变成了 "C++ Tutorial!"。

如果我们的目的本来就是让同一个字符串变量继续变长,下面 2 种方式是等价的:

// 方式 1(推荐)
text += " Tutorial";

// 方式 2
text = text + " Tutorial";

其中,方式 2 每次都要先生成一个新的临时字符串,然后再复制回 text。而方式 1 是直接在原字符串的末尾追加内容,省去了反复创建临时字符串的开销。这一点在结合 for 循环持续拼接时尤其明显,下面我们来看一个例子。

示例 3:在循环中使用 += 拼接

#include <iostream>
#include <string>

int main() {
    std::string langs[3] = {"[C++]", "[Python]", "[Go]"};
    std::string line;

    for (int i = 0; i < 3; i++) {
        line += langs[i];
    }
    std::cout << line << '\n';
    return 0;
}

运行结果如下。

[C++][Python][Go]

分析:

上面代码中,line 初始为空字符串,每次循环都会通过 line += langs[i]; 把数组中的元素直接追加到 line 末尾,循环执行 3 次后就得到了 "[C++][Python][Go]"。

在实际开发中,凡是在循环里不断往同一个字符串后面追加内容,我们都优先选择 += 运算符。

使用 append() 函数

除了 += 运算符之外,std::string 还提供了 append() 成员函数,同样用于把新内容追加到当前字符串的末尾。

语法:

str.append(追加文本);
str.append(count, ch);

说明:

其中,append 在英文中是 “追加、附加” 的意思,常用的有以下 2 种传参形式:

  • append(追加文本):直接往字符串末尾追加一段文本,作用跟 += 相同。
  • append(count, ch):往字符串末尾连续追加 count 个相同的 char 字符 ch,比如 append(3, '!') 表示连续追加 3 个感叹号。

示例 4:append() 追加字符

#include <iostream>
#include <string>

int main() {
    std::string title = "Chapter 5";
    title.append(": Strings");
    title.append(3, '!');

    std::cout << title << '\n';
    return 0;
}

运行结果如下。

Chapter 5: Strings!!!

分析:

在这个例子中,title.append(": Strings") 先把 ": Strings" 追加到末尾,接着 title.append(3, '!') 连续追加了 3 个 '!' 字符,最终得到 "Chapter 5: Strings!!!"。

平时如果只是简单追加一段文本或单个字符,直接写 += 更简短好读。当我们需要连续追加多个相同字符时,比如调用 append(20, '-') 生成一条分隔横线,再使用双参数的 append(count, ch) 就可以了。

使用 std::to_string() 拼接数字

在编写程序时,我们还经常需要把文字和数字拼成一句话,比如把 "年龄:" 和整数 20 拼成 "年龄:20"。

接触过 Java 或 JavaScript 的小伙伴,可能会习惯直接写 "年龄:" + 20。但在 C++ 中,std::string 不能直接使用 + 或 += 与数字拼接,必须先调用 std::to_string() 函数把数字转换成字符串才行。

语法:

std::to_string(val)

说明:

std::to_string() 同样包含在 <string> 头文件中,它可以把 int、long、double 等数值类型的变量或字面量 val 转换为对应的 std::string 字符串。

示例 5:拼接字符串与数字

#include <iostream>
#include <string>

int main() {
    int age = 20;
    double score = 95.5;

    std::string info1 = "年龄:" + std::to_string(age);
    std::string info2 = "成绩:" + std::to_string(score);

    std::cout << info1 << '\n';
    std::cout << info2 << '\n';
    return 0;
}

运行结果如下。

年龄:20
成绩:95.500000

分析:

std::to_string(age) 先把整数 20 转换成字符串 "20",再与 "年龄:" 拼成 "年龄:20"。传入小数 95.5 时,std::to_string() 默认保留 6 位小数,因此得到了 "95.500000"。

这里小伙伴们要注意,不能跳过转换直接把字符串和数字相加。下面这种写法就是错误的,编译时会直接报错:

std::string prefix = "年龄:";
std::string info = prefix + 20;

常见问题

1. 如果需要控制小数位数,或者一次把很多变量拼成复杂字符串,应该怎么做?

当只是简单拼接一两个整数时,使用 + 配合 std::to_string() 最直接。如果变量较多,或者不想让小数末尾拖着一串多余的 0,后面章节还会专门介绍以下 2 种格式化方式:

使用格式化函数:在 C++20 中推荐使用 std::format(),通过占位符 {} 就能按指定小数位数把多个变量拼成字符串。

使用字符串流:在较早的标准中可借助 <sstream> 里的 std::ostringstream,像写 std::cout << 一样把各种数据写入流中完成拼接。

上一篇:

下一篇:

给站长反馈

绿叶网正在不断完善中,小伙伴们如果发现任何问题,还望多多给站长反馈,谢谢!

邮箱:lvyenet@vip.qq.com

「绿叶网」服务号
绿叶网服务号放大
关注服务号,微信也能看教程。
绿叶网服务号