当前位置:网站首页>统计UTF-8字符串中的字符函数
统计UTF-8字符串中的字符函数
2022-07-31 19:18:00 【棉花糖超人】
前言
在实际的工作开发中,需要对UTF-8字符串中的字符进行统计,但字符可能占用多个字节 ,所以此时统计字节个数是不满足实际功能需求
主要涉及到的知识点为:位运算、补码、Unicode字符集、UTF-8编码规则
Unicode与UTF-8的区别?
ASCII码
在计算机中每八个二进制位组成了一个字节(Byte),一个二进制有两种状态:”0” 状态 和 “1”状态,八位的字节一共可以组合出256(2的八次方)种不同的状态,计算机在最开始只在美国使用,早期人们用 8 位二进制来编码英文字母(最前面的一位是 0),将英文字母和一些常用的字符分别用连续的字节状态表示,一直编到127就可以用不同字节来存储英文的文字,于是就把这个方案叫做ANSI的ACII编码
ANSI的ACII编码只限定于表示英文的文字,对于其他国家和地区的特殊字符无法进行编码,于是各个国家就决定把字节中最前面未使用的那一个位拿来使用,一直把序号编到了最后一个状态255用来表示新的字母、符号,所以从128~255这一字符集叫做"扩展字符集"
但是由于每个国家对于"扩展字符集"赋予了不同的含义,即国家之间可能存在不同的编码方式,这样容易导致乱码的形成
Unicode
Unicode就是为了统一世界上所有字符,将这些分配了一个唯一的数字编号,这个编号范围从 0x000000 到 0x10FFFF (十六进制),有 110 多万,每个字符都有一个唯一的 Unicode 编号,这个编号一般写成 16 进制,在前面加上 U+。例如:“马”的 Unicode 是U+9A6C
Unicode只规定了符号编码范围 ,并没有指定符号的存储方式,所以符号怎么存储还是需要对应的编码规则
UTF-8
UTF(UCS Transfer Format)标准是为了解决unicode如何在网络上传输的问题,UTF-8就是每次8个位传输数据,虽然每次是使用8位进行传输,但实际是可变长字节的,就是使用的字节是可变的,这个可变取决了该字符在Unicode的编码大小,编号小的使用的字节就小,编号大的使用的字节就相应增多
UTF-8编码规则
1、对于单字节的符号,字节的第一位为0,后面的七位为Unicode码,因为对于英文字母,Unicode码和ASCII码是一致的
2、对于n字节的符号(n>1),第一个字节的前 n 位都设为 1,第 n+1 位设为 0,后面字节的前两位一律设为 10,剩下的没有提及的二进制位,全部为这个符号的 Unicode 码
“马”的 Unicode 编号是:0x9A6C,整数编号是 39532,对应第三个范围(2048 - 65535),其格式为:1110XXXX 10XXXXXX 10XXXXXX,39532 对应的二进制是 1001 1010 0110 1100,将二进制填入进入就为: 11101001 10101001 10101100
源码
int strlenUtf8(const char *s)
{
int i = 0, j = 0;
while (s[i]) {
if ((s[i] & 0xc0) != 0x80){
j++;
}
i++;
}
return j;
}
代码分析
该函数主要是针对UTF-8字符串的字符统计,所以首先得清楚UTF-8编码规则和Unicode字符集的区别,其次是&位运算

位运算
(s[i] & 0xc0) != 0x80
0xC0=0b11000000
0x80=0b10000000
& 代表 按位逻辑与
要满足该表达式则s[i]的前两位为11,即11101001 10101001 10101100 只有11101001满足该表达式
在计算机内存中,整数一致采用补码的形式存储,所以汉字符号"马"对应的三个字节分别为-23、-87、-84
总结
对UTF-8字符串中的字符进行统计主要考察的知识点是位运算、补码、Unicode字符集、UTF-8编码规则,希望通过分享的代码一起来学习,来进步,也希望有错误的地方大佬能指出,peace&love
边栏推荐
- Unity 之 音频类型和编码格式介绍
- Apache EventMesh distributed event-driven multi-runtime
- Mobile web development 02
- PCB叠层设计
- -xms -xmx(information value)
- 获取抖音视频详情 API
- 架构师04-应用服务间加密设计和实践
- Made with Flutter and Firebase!counter application
- The server encountered an internal error that prevented it from fulfilling this request的一种解决办法[通俗易懂]
- 【NLP】什么是模型的记忆力!
猜你喜欢
【码蹄集新手村600题】通向公式与程序相结合
useragent在线查找
杰理语音芯片ic玩具芯片ic的介绍_AD14NAD15N全系列开发
MySQL---Subqueries
35 MySQL interview questions and diagrams, this is also easy to understand
新型电信“套路”,我爸中招了!
[PIMF] OpenHarmony Thesis Club - Inventory of the open source Hongmeng tripartite library [3]
All-platform GPU general AI video supplementary frame super-score tutorial
[TypeScript] OOP
第七章
随机推荐
c语言解析json字符串(json对象转化为字符串)
MySQL---单行函数
返回一个零长度的数组或者空的集合,不要返回null
2022年Android 面经总结(附含面试题 | 源码 | 面试资料)
MySQL---operator
INeuOS industrial Internet operating system, the equipment operational business and "low code" form development tools
程序员如何学习开源项目,这篇文章告诉你
SiC MOSFET的短路特性及保护
Taobao/Tmall get Taobao password real url API
Three.js入门
MySQL---Subqueries
Given an ip address, how does the subnet mask calculate the network number (how to get the ip address and subnet mask)
-xms -xmx(information value)
【码蹄集新手村600题】通向公式与程序相结合
Bika LIMS 开源LIMS集—— SENAITE的使用(检测流程)
架构师04-应用服务间加密设计和实践
微信小程序的路由拦截
手把手教你学会部署Nestjs项目
MySQL - multi-table query
STM32 full series development firmware installation guide under Arduino framework