c++oding="utf-8" ?>
utf-8字节序列合法性检查需严格遵循rfc 3629前缀规则,手动遍历并用状态机验证:识别起始字节类型后,检查续字节是否为0x80–0xbf;排除超长编码(如0xc0/c1)、越界起始(0xf5–0xff)、续字节缺失及超出u+10ffff的编码;遍历时须将char转为unsigned char避免符号扩展错误。

UTF-8字节序列合法性检查的核心逻辑
合法UTF-8不是“能解码成Unicode”,而是“字节序列本身符合RFC 3629定义的前缀规则”。C++标准库不提供现成函数,std::string只存字节,不会自动校验——你必须手动遍历、按状态机判断每个字节是否处于正确位置。
如何逐字节验证UTF-8编码(无第三方库)
关键在于识别起始字节类型(ASCII/2字节/3字节/4字节),再检查后续字节是否为0x80–0xBF范围内的续字节。常见错误是忽略“超长编码”和“代理对禁止”这两类非法情况:
-
0xC0、0xC1开头的2字节序列是非法的(它们只能编码U+0000–U+007F,但ASCII已有单字节表示) -
0xF5–0xFF开头的字节直接非法(UTF-8最多支持U+10FFFF,对应0xF4起始) - 续字节缺失或错位(如
0xE0 0x80只有两个字节,但0xE0要求跟两个续字节) - 编码超出Unicode范围(如
0xF4 0x90 0x80 0x80解码为U+110000,非法)
std::string中调用时要注意的边界问题
不能简单用for (auto c : s),因为char可能是有符号的,导致0x80–0xFF被解释为负数,比较出错。务必把每个字节转为unsigned char再判断:
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
for (size_t i = 0; i (s[i]);
if (b = s.size() || (static_cast<unsigned char>(s[i+1]) & 0xC0) != 0x80)
return false;
i += 2;
}
// ... 其他分支同理
}</unsigned>
还要注意空字符串、嵌入\0字节(std::string允许)、以及中间截断的多字节序列——这些都算非法。
为什么不用std::codecvt_utf8或iconv
std::codecvt_utf8在C++17已被弃用,且多数实现(如libstdc++)对非法输入行为未定义;iconv默认将非法序列转为空字符或报错,不提供细粒度校验能力。真正需要“仅检查不转换”的场景,手写状态机最可靠、最轻量、最可控。
最易被忽略的是:UTF-8合法性 ≠ 文本可读性。一个完全合法的UTF-8字符串可能包含控制字符、BOM、或无法显示的Unicode字符——校验只管字节结构,不管语义。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










