如何实现UTF-8字符串截断函数:适配指定字节长度且不破坏字符
UTF-8字符串安全截断实现方案
需求:实现一个函数shorted_uft8_string,接收UTF-8编码的字符串和最大字节长度,通过移除最短的后缀让结果的字节数不超过指定最大值,核心要求是不能截断UTF-8字符的中间部分,避免出现乱码。
实现思路
- 先判断原字符串字节长度是否已满足要求,若满足直接返回原字符串
- 若需要截断,从目标最大长度的位置往前遍历,找到第一个合法的UTF-8字符起始字节:
- 单字节UTF-8字符的起始字节以
0开头(二进制0xxxxxxx) - 多字节UTF-8字符的起始字节以
11开头(二进制11xxxxxx) - 多字节字符的后续字节均以
10开头(二进制10xxxxxx),这类字节不能作为截断位置
- 单字节UTF-8字符的起始字节以
- 截断到找到的合法起始字节位置,确保结果是完整的UTF-8字符串
完整代码实现
#include <string> #include <cassert> std::string shorted_uft8_string(std::string str, size_t max_length) { // 原字符串长度已符合要求,直接返回 if (str.length() <= max_length) { return str; } // 从max_length位置往前找合法的UTF-8起始字节 size_t truncate_pos = max_length; while (truncate_pos > 0) { unsigned char c = static_cast<unsigned char>(str[truncate_pos]); // 判断当前字节是否是多字节字符的后续字节(10xxxxxx) if ((c & 0xC0) != 0x80) { // 找到合法起始字节,停止遍历 break; } truncate_pos--; } // 截断到合法位置 str.resize(truncate_pos); assert(str.length() <= max_length); return str; }
代码说明
- 边界处理:先检查原字符串长度是否小于等于
max_length,如果是直接返回,避免不必要的计算 - 寻找合法截断点:从
max_length位置开始向前遍历,跳过所有多字节字符的后续字节(10xxxxxx格式),直到找到一个合法的起始字节 - 截断与验证:调用
resize截断字符串,最后用assert确保结果长度符合要求
内容的提问来源于stack exchange,提问作者pic11
相关产品推荐
相关产品推荐

