最安全的拼接方式是用 std::string;需转为 std::string 再拼接,不保证零终止时显式传长度;输出到 char[] 优先用 snprintf;高频场景可 reserve+append;utf-8 拼接无问题,但后续处理需注意编码和字节/字符混淆。

用 std::string 拼接最安全,别碰裸 char[]
直接操作原始字符数组(比如 char a[10], b[20])拼接,极易越界、漏结尾符、内存重叠——不是“能不能”,是“不值得冒这个风险”。现代 C++ 的标准解法就是转成 std::string 再拼:
char a[] = "hello"; char b[] = "world"; std::string s = std::string(a) + std::string(b); // "helloworld"注意:这里
std::string(a) 依赖 a 以 '\0' 结尾;如果源数组不保证零终止(比如从二进制数据读来的),得显式传长度:std::string(a, len)。
需要输出到固定大小的 char[]?先算长度再复制
有些场景必须写回 C 风格数组(如调用旧 API),这时不能靠 strcat 盲拼——它不检查目标缓冲区大小,一越界就 UB。正确做法是:
- 用
strlen或手动遍历算出所有源字符串总长(别忘加 1 给结尾'\0') - 确认目标数组足够大,否则截断或报错
- 用
strcpy+strcat,或更安全的snprintf
char a[] = "foo"; char b[] = "bar"; char out[32]; snprintf(out, sizeof(out), "%s%s", a, b); // 自动截断+补 '\0'用
snprintf 比 strcpy/strcat 组合更可靠,尤其当输入长度不确定时。
性能敏感?避免重复构造 std::string
如果在循环里高频拼接(比如日志组装),反复创建临时 std::string 对象会有小开销。可改用 std::string 的 reserve() + append():
std::string result; result.reserve(100); // 预分配,避免多次 realloc result.append(a); result.append(b); result.append(c);注意:
reserve() 不改变 size(),只影响容量;append() 比 += 在某些实现下略高效,但差别极小——除非 profiler 真标出它是瓶颈,否则优先写清晰。
遇到中文或 UTF-8 字符串?编码没变,但逻辑要小心
std::string 和 char[] 本身不区分编码,UTF-8 中文字符占多个字节,但拼接操作(+、append、snprintf)依然按字节处理,完全没问题。真正容易出错的是:
- 用
strlen当“字符数”用(它返回字节数,一个中文通常是 3 字节) - 用
strncpy截取“前 5 个汉字”(会切在中间,导致乱码) - 把拼接结果传给只支持 GBK 的旧系统而没转码
多字符数组拼接这件事,核心陷阱不在“怎么连”,而在“连完往哪放、谁来管边界、谁负责编码对齐”。盯着 std::string 做中转,比手撸 memcpy 安全十倍;真要落回 char[],snprintf 是目前最省心的兜底方案。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











