【C++练习】27.在C++中连接字符串而不使用“strcat“函数
目录
-
- 方法一:使用 "std::string" 的运算符
- 方法二:使用 "std::string" 的成员函数
- 方法三:使用 "std::stringstream"
- 方法四:手动操作字符数组
- 性能与使用建议
在C++中连接字符串而不使用"strcat"函数,有多种方法可供选择,每种方法各有其适用场景。
下表概括了这些核心方法的特性,方便你快速比较和选择。
| 方法类别 | 核心思路 | 关键函数/运算符 | 是否修改原字符串 | 主要适用场景 |
|---|---|---|---|---|
| std::string运算符 | 使用重载的运算符直观拼接 | “+”, “+=” | "+"否 / "+="是 | 简单、少量的字符串拼接 |
| std::string成员函数 | 调用成员函数实现功能更丰富的追加 | “append()”, “insert()” | 是 | 需要链式调用或指定子串等复杂追加 |
| 字符串流 | 利用流操作符拼接多种类型数据 | “std::stringstream” | 否(生成新字符串) | 复杂的格式化拼接,如混合字符串和数字 |
| 手动字符数组操作 | 底层操作,手动遍历并复制字符 | 循环、索引 | 是(针对字符数组) | 需直接操作字符数组、理解底层原理 |
方法一:使用 “std::string” 的运算符
这是最直观和常用的方式,得益于C++标准库对
“std::string” 的重载。
- “+” 运算符:用于连接两个或多个字符串并返回一个新的字符串对象,不会修改参与拼接的原始字符串。
#include <iostream>
#include <string>
int main() {
std::string str1 = "Hello, ";
std::string str2 = "world!";
std::string result = str1 + str2; // 连接
std::cout << result << std::endl; // 输出:Hello, world!
// 也可以连接多个内容
std::string result2 = str1 + "C++" + " " + str2;
std::cout << result2 << std::endl; // 输出:Hello, C++ world!
return 0;
}
注意:使用 “+” 运算符时,至少一端必须是 “std::string” 类型对象。直接对两个C风格字符串字面量(如 ““Hello” + “World””)使用 “+” 是错误的。
- “+=” 运算符:将一个字符串追加到另一个字符串的末尾,会直接修改左边的原字符串。这种方式效率较高,适合逐步构建字符串。
#include <iostream>
#include <string>
int main() {
std::str message = "Hello";
message += ", "; // 追加字符串字面量
message += 'C'; // 追加单个字符
message += "+="; // 追加另一个std::string
std::cout << message << std::endl; // 输出:Hello, C+=
return 0;
}
方法二:使用 “std::string” 的成员函数
这类方法通过调用成员函数来修改字符串,提供了更灵活的操作。
- “append()” 函数:功能与 “+=” 类似,但支持更多参数形式,如追加子串、指定数量的字符等,非常适合链式调用。
#include <iostream>
#include <string>
int main() {
std::string base = "The answer is ";
base.append(3, '!'); // 追加3个感叹号
std::cout << base << std::endl; // 输出:The answer is !!!
std::string other = "a long sentence.";
base.append(other, 2, 5); // 将other从索引2开始的5个字符追加到base
std::cout << base << std::endl; // 输出:The answer is !!! long
// 链式调用示例
std::string str = "Start";
str.append(" ->").append(" Middle").append(" -> End");
std::cout << str << std::endl; // 输出:Start -> Middle -> End
return 0;
}
- “insert()” 函数:主要功能是在指定位置插入字符串,也可用于在字符串开头或中间实现“连接”效果。
#include <iostream>
#include <string>
int main() {
std::string str = "world!";
str.insert(0, "Hello, "); // 在位置0(开头)插入
std::cout << str << std::endl; // 输出:Hello, world!
return 0;
}
方法三:使用 “std::stringstream”
当需要进行复杂的格式化拼接,特别是混合了字符串、数字等多种数据类型时,“std::stringstream” 是一个非常强大的工具。它使用流插入运算符 “<<” 来拼接内容,代码可读性高。
#include <iostream>
#include <sstream> // 需要包含此头文件
#include <string>
int main() {
std::string name = "Alice";
int age = 25;
double score = 99.5;
std::stringstream ss;
ss << "Name: " << name << ", Age: " << age << ", Score: " << score;
std::string result = ss.str(); // 获取拼接后的整个字符串
std::cout << result << std::endl; // 输出:Name: Alice, Age: 25, Score: 99.5
return 0;
}
需要注意的是,“stringstream” 的性能通常不如直接使用 “std::string” 的运算符或成员函数,因此更适用于调试、日志记录等对性能不敏感的格式化输出场景。
方法四:手动操作字符数组
这种方法更接近底层,能帮助你理解字符串操作的原理,但在日常开发中不如使用 “std::string” 安全便捷。基本思路是:为目标数组分配足够空间(包括结束符"\0"),然后逐个字符地复制内容。
#include <iostream>
#include <cstring> // 用于strlen
int main() {
const char str1[] = "Hello, ";
const char str2[] = "world!";
// 1. 计算总长度(注意包括结束符 '\0')
size_t total_len = std::strlen(str1) + std::strlen(str2) + 1;
// 2. 分配足够大的字符数组
char* result = new char[total_len];
// 3. 复制第一个字符串
size_t i = 0;
for (; str1[i] != '\0'; ++i) {
result[i] = str1[i];
}
// 4. 复制第二个字符串
for (size_t j = 0; str2[j] != '\0'; ++j, ++i) {
result[i] = str2[j];
}
// 5. 添加字符串结束符
result[i] = '\0';
std::cout << result << std::endl; // 输出:Hello, world!
// 6. 释放动态分配的内存
delete[] result;
return 0;
}
重要提示:此方法需要手动管理内存,务必确保分配的空间足够大,否则可能导致缓冲区溢出。在现代C++程序中,应优先考虑使用
“std::string”。
性能与使用建议
-
性能关键场景:在需要循环拼接大量字符串时,使用 “reserve()” 函数预先为 “std::string” 分配足够的空间,可以避免反复重新分配内存,从而大幅提升 “+=” 或 “append()” 的效率。
-
简单拼接:"+" 和 “+=” 运算符最直观方便。
-
灵活追加:需要追加子串或链式调用时,选择
“append()”。 -
格式化拼接:混合字符串、数字等其他类型时,“std::stringstream” 是理想选择。
更多推荐

所有评论(0)