手动切分 std::string 时需避免 UTF-8 中文乱码,应按字符而非字节截取;推荐遍历判断 UTF-8 起始字节或转宽字符;英文需保单词完整,中文可依标点分词;显示宽度须考虑字体渲染差异,不能依赖 string::length()。

用 std::string 手动切分时,注意中文字符和 UTF-8 编码边界
直接按字节长度切分会导致中文乱码,因为 UTF-8 中一个汉字占 2–4 字节。不能简单用 substr(0, n) 截取前 n 个字节。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 用
std::mbstowcs或第三方库(如 ICU、utf8cpp)先转成宽字符,再按字符数切分 - 更轻量的做法:遍历字节,用 UTF-8 首字节特征判断字符起始(
0xC0–0xFF表示多字节字符开头,0x80–0xBF是后续字节),跳过中间字节 - 如果确定只处理 ASCII,可放心用
substr+find_last_of(" ", pos)往回找空格
用 std::regex 做“软换行”容易踩空匹配或性能陷阱
std::regex 在 C++11 中实现质量参差,MSVC 和 libstdc++ 对 Unicode 支持弱,且正则回溯在长文本中可能卡顿。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 避免写类似
R"((.{1,20})(?=\s|$))"这种带前瞻的模式——它在无空格长单词时会失败 - 若必须用正则,优先用
std::regex_iterator分批提取,而非一次性regex_replace - 对性能敏感场景(如日志渲染),改用状态机式循环,比正则快 5–10 倍
实际排版需求常要保留单词完整性,不能只看字符数
用户看到“每个 20 字符换行”不等于真按 20 切——英文单词被截断体验极差,中文虽无空格但仍有语义词组。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 先按空格/标点分割为 token,再贪心合并:每行累积 token 直到加下一个就超长
- 对中文,可接入轻量分词(如
cppjieba),或退化为“最长不超过 N 字,往左找最近的顿号、逗号、句号” - 记住:换行位置最终要返回的是字节索引(用于插入
"\n"),不是字符索引
输出到终端或 GUI 时,要考虑目标环境的实际宽度和字体渲染
字符串里插了 "\n" 不代表显示就对齐——等宽字体下 1 个 ASCII 占 1 格,1 个中文占 2 格(East Asian Width = Fullwidth),而 std::string::length() 全部返回 1。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 计算显示宽度需用
wcswidth(POSIX)或手动查 Unicode EastAsianWidth 属性 - Qt 中用
QFontMetrics::horizontalAdvance();Windows 控制台可用GetConsoleScreenBufferInfo获取列数 - 别在逻辑层硬编码“每行 80 字符”,应把最大显示宽度作为参数传入换行函数


















