std::reverse(str.begin(), str.end()) 是绝大多数场景下字符串反转的最佳选择,需确保迭代器范围正确,避免越界、不可修改内存及 unicode 乱码等问题。

直接用 std::reverse 最省事,但得注意迭代器范围
绝大多数场景下,std::reverse 就是最佳选择,它在 <algorithm></algorithm> 头文件里,作用于任意双向迭代器区间。关键不是“能不能用”,而是“范围写对没”——常见错误是传入 str.begin() 和 str.end() 以外的迭代器,比如误用 str.c_str() 或手动计算偏移出错。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 对
std::string直接用std::reverse(str.begin(), str.end()),无需额外判断空串,STL 内部已处理 - 若操作子串(如反转从位置 2 开始的 5 个字符),写成
std::reverse(str.begin() + 2, str.begin() + 2 + 5),务必确保右边界不越界,否则未定义行为 - 不要对 C 风格字符串字面量(如
"hello")直接调用std::reverse,它们是 const char[],不可修改;先拷贝到std::string或std::vector<char></char>
手写循环反转更可控,适合教学或嵌入式环境
当不能依赖 STL(如裸机开发、内存受限场景),或需要明确控制每一步(比如跳过某些字符、按 UTF-8 码点反转),就得自己写双指针循环。这不是为了炫技,而是规避 std::reverse 的黑盒行为。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 用
size_t i = 0, j = s.length();时注意:j应初始化为s.length() - 1,否则s[j]会越界访问 - 循环条件用
i ,不是 <code>i ,否则中间字符会被交换两次,等于白干 - 如果字符串含嵌入 null(
'\0'),std::string本身支持,但手写时别误用strlen()判长度——它遇 \0 就停,会截断
std::string 的 assign + rbegin/rend 是最安全的只读方案
如果你不想原地修改原字符串,而是想生成一个新反转副本(比如函数返回值、日志打印前处理),用 assign 构造比先拷贝再 reverse 更高效,也更清晰表达意图。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 写成
std::string reversed = std::string(s.rbegin(), s.rend());,这是标准、无副作用的方式 - 避免
reversed.assign(s.rbegin(), s.rend())后再reversed += "extra"这类混用,容易混淆可变/只读语义 - 注意
rbegin()/rend()返回的是反向迭代器,不能和普通begin()/end()混用,比如std::reverse(s.rbegin(), s.rend())是无效操作,编译不过
Unicode 字符串反转不能靠 std::reverse 简单处理
如果字符串含 emoji 或带组合符的字符(如 `é` 写作 `e\u0301`),std::reverse 会按字节或码元反转,导致组合符脱离基字符,显示乱码。这不是 bug,是它本就不承诺 Unicode 意义上的“字符”反转。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 确认输入是否可能含 Unicode:若来自用户输入、网络或文件,一律按 UTF-8 处理
- 真要正确反转,得先用 ICU、UTF8-CPP 或 C++20 的
<unicode></unicode>(实验性)做 grapheme cluster 分割,再倒序拼接 - 简单绕过法:若业务允许,统一转成 NFC 标准化形式后,再用
std::string反转——但仍有风险,仅适用于有限字符集
实际项目里,90% 的字符串反转用 std::reverse(str.begin(), str.end()) 就够了;剩下那 10%,问题往往不出在“怎么反转”,而出在“你到底想反转什么单位”——字节?码元?Unicode 标量值?还是用户眼中的“字”?这个边界模糊点,最容易被忽略。











