统计UTF-8字符串中的字符函数

杰尼龟冲刺

前言

在实际的工作开发中,需要对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字符集的区别,其次是&位运算

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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值