insert() 是在 std::string 指定位置插入字符的标准安全方法,支持单字符(str.insert(pos, 1, ch))和字符串片段插入,pos 必须 ≤ 字符串长度,超出则抛出 std::out_of_range。

用 insert() 在指定位置插入字符最直接
想往 std::string 里插单个字符,insert() 是标准且安全的选择。它支持两种常用重载:一种插单个字符,一种插字符串片段。
- 插单个字符:调用
str.insert(pos, 1, ch),其中pos是插入下标(从 0 开始),ch是char类型值 - 插字符串字面量:用
str.insert(pos, "x"),但注意这会插入整个 C 风格字符串(含结尾\0?不,std::string自动截断,实际只插"x"的内容) -
pos必须 ≤ 字符串长度,允许等于(即在末尾插入),超出会抛出std::out_of_range
示例:
std::string s = "hello"; s.insert(2, 1, 'X'); // 变成 "heXllo"
用 substr() 拼接也能实现,但不推荐
有人习惯切片再拼接:s = s.substr(0, pos) + "x" + s.substr(pos)。语法上可行,但有明显代价:
- 每次调用
substr()都触发内存分配和拷贝,pos靠后时尤其低效 - 原字符串被丢弃,新字符串重建,对长字符串或高频操作影响明显
- 如果
pos == s.length(),第二个substr()返回空串,逻辑没错,但掩盖了边界意图
除非你明确需要不可变语义或正在写函数式风格代码,否则绕开 insert() 纯属自找麻烦。
别用 operator[] 或 at() 直接赋值来“插入”
s[pos] = 'x' 或 s.at(pos) = 'x' 是**替换**,不是插入 —— 它们不会移动后续字符,也不会改变字符串长度。常见误用场景:
立即学习“C++免费学习笔记(深入)”;
- 想在中间加一个字符,却写了
s[3] = 'a',结果只是把第 4 个字符改成'a',原长度不变 - 若
pos == s.length(),[]行为未定义,at()会抛异常,根本达不到“追加”效果 - 真正要追加,该用
push_back()或+=,而不是强行越界赋值
注意迭代器失效和线程安全
insert() 会修改字符串内部存储,可能触发重新分配,导致所有现存迭代器、指针、引用失效:
- 如果你在循环中边遍历边
insert(),迭代器很可能指向已释放内存,行为未定义 - 多线程环境下,对同一
std::string对象并发调用insert()或其他非常量成员函数,必须加锁 ——std::string本身不保证线程安全 - 某些旧编译器(如 GCC 5 以前)的
std::string实现采用 copy-on-write,insert()可能意外触发深拷贝;现代标准库已弃用该优化,但若需兼容老旧环境,仍需留意
插入点越靠近开头,移动的字符越多;越靠近末尾,开销越小。真要频繁在头部插入,考虑换用 std::deque<char></char>。


















