如何实现统计带\0的UTF-8格式C字符串字符数的函数?
统计UTF-8格式C字符串的字符数实现方案
核心逻辑梳理
UTF-8是变长编码,字符的字节数由首字节的高位标识:
- 单字节字符(ASCII):首字节最高位为
0(二进制0xxxxxxx),占1字节 - 双字节字符:首字节最高两位为
110(二进制110xxxxx),后续跟1个格式为10xxxxxx的续字节 - 三字节字符:首字节最高三位为
1110(二进制1110xxxx),后续跟2个续字节 - 四字节字符:首字节最高四位为
11110(二进制11110xxx),后续跟3个续字节
实现步骤
- 遍历字符串字节,直到遇到终止符
\0 - 对每个首字节,通过位运算判断其所属的字符类型,确定需要跳过的续字节数量
- 每处理完一个完整字符,计数器加1
- 跳过对应数量的续字节,继续下一个首字节的判断
代码实现
#include <stddef.h> size_t count_utf8_characters(const char *str) { size_t char_count = 0; // 转成unsigned char避免有符号char的符号位干扰位运算 const unsigned char *byte_ptr = (const unsigned char *)str; while (*byte_ptr != '\0') { if ((*byte_ptr & 0x80) == 0) { // 单字节ASCII字符 char_count++; byte_ptr++; } else if ((*byte_ptr & 0xE0) == 0xC0) { // 双字节UTF-8字符,跳过1个续字节 char_count++; byte_ptr += 2; } else if ((*byte_ptr & 0xF0) == 0xE0) { // 三字节UTF-8字符,跳过2个续字节 char_count++; byte_ptr += 3; } else if ((*byte_ptr & 0xF8) == 0xF0) { // 四字节UTF-8字符,跳过3个续字节 char_count++; byte_ptr += 4; } else { // 非法UTF-8字节,默认跳过当前字节(可根据需求添加错误处理) byte_ptr++; } } return char_count; }
关键细节说明
- 转换为
unsigned char*:避免有符号char在高位为1时被解析为负数,导致位运算结果异常 - 位掩码的作用:通过
&运算匹配首字节的高位特征,快速判断字符的字节长度 - 非法字节处理:遇到不符合UTF-8规范的字节时,默认跳过单个字节,实际项目中可根据需求增加合法性校验或错误抛出逻辑
内容的提问来源于stack exchange,提问作者philippe82000
相关产品推荐
相关产品推荐

