C++截取定长utf8字符及字符集与字符编码总结
博客搬家,原地址:https://langzi989.github.io/2017/11/09/C++截取utf8字符以及字符编码记录/
之前有个需求要求从一段utf8编码的文字中截取前n个字符,由于文字中包含既有中文又有数字字母等,这些字符所占的字节数都不相同,所以直接截取前M个字符可能会导致乱码问题。在完成截取之前,需要先了解utf8编码字符的存储规则。后面简单介绍一下常见的字符集及字符编码
utf8编码规则
在理解utf8编码规则之前先说一下utf16和utf32的编码规则,utf32规定所有的unicode字符集上的所有字符都是用32bit来存储,即可存储的字符数可达2^32个,接近40亿,这明显可以容纳已有的所有字符。utf16编码使用2个字节存储,超过此范围的使用其他特殊技巧处理。使用utf16和utf32有一个问题,就是会受到计算机存储大端规则和小端规则的影响。所以utf16又有utf16_LE和utf16_BE之分。为了解决这个问题,需要在文本文件的开头定义一个BOM(Byte order Mark),这是一个非打印标志,用此标志来标志当前文本存储是大端存储还是小端存储。
utf8是一种针对unicode的可变长度字符编码,也是一种前缀码,它可以表示unicode标准中的任何字符。且与ascii码兼容,这使得我们处理ascii字符的时候不许做特殊修改。
utf8使用1~6个字符为每个字符编码,但实际使用中只使用了4个。
utf8编码规则:
(1)对于单字节字符,字节的第一位为0,后面7位为这个字符的unicode码,因此对于ascii码,unicode与ascii保持一致。
(2)对于n字节符号(n>1),第一个字节的前n位都为1,第n+1位为0,其他字节的前两位都为10,其余位为实际的unicode位。
规则:
unicode范围 | 二进制表示范围 |
---|---|
U-00000000 - U-0000007F | 0xxxxxxx |
U-00000080 - U-000007FF | 110xxxxx 10xxxxxx |
U-00000800 - U-0000FFFF | 1110xxxx 10x |