UTF8编码、解码和UTF16编码、解码在VC中
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
UTF 8编码、解码和UTF 16编码、解码在VC中计算机的符号编码有很多种如经典的ASCII编码Unicode编码UTF-8编码UTF-16编码UCS-2编码UCS-4编码等其中ASCII编码是最具代表性的由一个Byte组成表示了英文字符、数字和全部键盘的控制符号Unicode编码是ASCII编码的发展有两个Byte表示一个字符可以表示6万多个字符由于英文字符只需要一个Byte表示即可用Unicode编码就造成了浪费当然表示中文时便比较合算了所以就引入了UTF-8编码。
本文主要介绍UTF-8编码和适合中文的UTF-16编码UTF-16的引入是由于6万多个空间对于汉字来说还是不够使用。
1.UTF-8编码先来看一个有趣的例子在记事本中只输入力量两个字保存后再次打开你发现了什么或者借用网上的微软与联通有仇的趣事输入联通两个字试试为什么会出现这种情况这就是UTF-8和GB2312惹的祸记事本默认的存储编码方式是ANSI编码这种编码是会随着计算机语言版本而改变在中文版本下它就是GB2312编码查看国标力的GB2312编码为0xC1A611000001 10100110量的GB2312编码为0xC1BF11000001 10111111所以第一次存储之后记事本中的二进制码为11000001 10100110 11000001 10111111再次打开记事本会先根据标识头来决定用什么编码方式打开和显示它看到没有任何标识头Unicode的标识头是FFFEUTF-8的标识头是EFBBBF不过有些老的UTF-8编码没有该标识头所以便在字节中添加了标识信息它便检查文本内所有字符的字节信息它看到1101011010这种信息11010是老的UTF-8编码的标识信息记事本便用UTF-8编码打开和显示该文本它先取出第一个11010格式的Unicode编码即星号所组成Unicode码00000000 011001100x0066找到对应字符f再取出第二个11010格式的Unicode编码00000000 011111110x007F找到对应字符DEL这自然不能正常显示在UtralEdit中可以看到显示的是f鞘卤镜南允痉绞接险tralEdit不同它什么都没显示。
然后再输入力量两个字保存后再次打开这次力量显示正常那又为什么因为这次保存的编码方式就是UTF-8因为它认为这是UTF-8编码格式所以加入了标识头EFBBBF而且将后来输入的力量两个字编成UTF-8编码格式因为用UTF-8编码格式打开所以用的是Unicode码而不是GB2312码力的Unicode码是0x529B01010010 10011011编成UTF-8编码格式是11100101 10001010 10011011三个字节量的Unicode码是
0x91CF10010001 11001111编成UTF-8编码是11101001 10000111 10001111而先前被认为是UTF-8格式的力量则不用变化自然还是显示不出来。
从上可以看出UTF-8编码有固定的格式而且字节数不定可以表示16个字节可以容纳031位如1字节0容纳7位
0x000x7F 2字节11010容纳11位0x800x07FF 3字节11101010容纳16位0x08000xFFFF 4字节11110101010容纳21位0x 0100000x1FFFFF 5字节11111010101010容纳26位0x 2000000x03FFFFFF 6字节11111101010101010容纳31位0x 040000000x7FFFFFFF 1.UTF-16编码UTF-16编码对古文的研究有重要意义因为中国文字大部份是两字节有的是四字节很多人可能没见过方正楷体S-超大字符集SIP这个字体里面存放的都是四字节的字模可以从下载相关字体Unicode编码与UTF-16编码的转换关系如下下面部分引用他人已经不知道出处字符按照UTF-16进行编码的规则是1.Unicode值小于0x10000的用等于该值的16位整数来表示。
2.Unicode值介于0x10000和0x10FFFF 之间的用一个值介于0xD800和0xDBFF在所谓的高8位区的16位整数和值介于
0xDC00和0xDFFF在所谓的低8位区的16位整数来表示。
3.Unicode值大于0x10FFFF 不能按照UTF-16进行编码。
注意在0xD800和0xDFFF间的值是特别为UTF-16预留所以不应该将任何字符的值指定为这个区间内的数值。
UTF-16编码将某个字符的
Unicode值转换为UTF-16的编码按照以下步骤进行。
假设U是给Unicode值小于
x10FFFF。
1如果U 0x10000U的编码就是无符号的十六位整数值和其本身的值一样处理结束。
2如果U等于或者小于0x10FFFF则设UU-0x10000。
此时U一定小于或者等于0xFFFFF也就是说U的值不会超过20位。
3分别初始化2个16位无符号的整数W1和W2为0xD800和0xDC00。
每个整数都有10位可以用来对字符进行编码正好能容纳U的20位。
4将U的高10位分配给W1的低10位将U的低10位分配给W2的低10位处理结束。
用数字来表示第2步到第4步如下所示Uyyyyyyyyyyxxxxxxxxxx W1110110 yyyyyyyyyy W2110111 xxxxxxxxxx UTF-16解码将单个字符从UTF-16解码为Unicode值的步骤如下。
设W1为待解码文字中第一个16位的整数设W2为跟在W1后的整数如果有的话。
1如果W1小于0xD800或者W1大于0xDFFF字符的值U就是W1的值处理结束。
2判断W1的值是否介于0xD800和0xDBFF之间。
如果不是那么顺序有误而且用W1将不能解码出任何合法字符。
处理结束。
3如果没有W2也就是说以W1结尾或者虽然有W2但不是介于0xDC00和0xDFFF之间那么顺序同样有错。
处理结束。
4建立一个20位的无符号整数U将W1的低10位作为U的高10位将W2的低10位作为U的低10位。
5将U的值加上0x10000以得到字符U的值处理结束。
在VC里面要输出四字节的字可以使用TextOuthdcintintLPCTSTRint其中的LPCTSTR必须是UTF16编码最后个数是2个。
当然可以使用DrawText函数输出。
但是只能在WindowsXP或以上版本才能很好的支持如果是Windows2000那么需要打补丁surreg。
如果是Windows98那么将不能使用只有自己读字体文件这里介绍一个很好的库FreeType2用它可以实现读取字体文件。