在实际开发中,我们经常需要把多段零散的文字连接成完整的一句话。在 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 << 一样把各种数据写入流中完成拼接。
