Windows API编程03-详解编码

联系WeChat:i-xiaodi,交流,付费课程学习

我们知道,计算机只能存储二进制数据,那么该如何表示和存储字符呢?这就需要使用字符集来实现字符与整数之间的转换。

ASCII(American Standard Code for Information Interchange,美国信息交换标准代码)

起始于20世纪50年代后期,在1967年定案,是基于拉丁字母的一套计算机编码系统,主要用于显示现代英语和其他西欧语言,它是现今通用的单字节编码系统。ASCII最初是美国国家标准,供不同的计算机在相互通信时作为共同遵守的西文字符编码标准,后来被国际标准化组织(International Organization for Standardization,ISO)定为国际标准,称为ISO 646标准。ASCII使用7位二进制数来表示128个字符,称为标准ASCII,包括所有的大写和小写字母、数字0~9、标点符号以及在美式英语中使用的特殊控制字符。

百度上可以看到相关的解信息:

● 0~31及127(共33个)是控制字符或通信专用字符,例如控制字符包括LF(换行)、CR(回车)、FF(换页)、DEL(删除)、BS(退格)、BEL(响铃)等;通信专用字符包括SOH(文头)、EOT(文尾)、ACK(确认)等。ASCII值8、9、10和13分别转换为退格、制表、换行和回车字符,它们并没有特定的图形显示,但会对文本显示产生影响。

● 32~126(共95个)是字符(32是空格),其中48~57为阿拉伯数字0~9;65~90为26个大写英文字母,

●97~122号为26个小写英文字母;其余为标点符号、运算符号等。由ASCII码表可以看到,数字符号、大写字母符号和小写字母符号的编码都是连续的,所以只要记住数字符号的编码从0x30开始、大写字母符号的编码从0x41开始以及小写字母符号的编码从0x61开始便可以推算出其他数字符号和字母符号的编码。

扩展ASCII

标准ASCII仅使用了每字节的低7位进行编码,最多可以表示128个字符。这往往不能满足实际需求,为此在IBM PC系列及其兼容机上使用了扩展的ASCII码。

扩展的ASCII码使用8位二进制数进行编码,扩展的ASCII包含标准ASCII中已有的128个字符,又增加了128个字符,总共是256个,值128~255用来表示框线、音标和其他欧洲非英语系的字母。1987年4月,MS DOS 3.3把代码页的概念带进了IBM。每个代码页都是一个字符集,并且这一概念后来也被用到了Windows系统里。这样一来,原本的IBM字符集成为第437页代码页,微软自己的MS DOS Latin 1字符集成为第850页代码页。其他的代码页为其他语言制定,就是说较低的128个ASCII码总是表示标准ASCII字符,而较高的128个ASCII码则取决于定义代码页的语言。代码页的数量以超乎想象的速度递增,后来更是出现了不同操作系统对于同一个国家语言的代码页互相不兼容的情况。每个系统环境的代码页都对标准字符集进行了修订,这使局面很混乱。

双字节字符集DBCS

单字节字符集肯定远远包含不了那些包括上万个字符的语言,例如中文、日文,因此这些国家都开发了表示自己本国文字的双字节字符集,用2字节(16位二进制数据)来表示除ASCII以外的字符(ASCII还是使用1字节来表示),其中常见的就是我国的GB系列编码了(GB为国标的拼音缩写)。不同国家创造出来的字符集虽说与ASCII兼容,但是编码却是互不兼容的,例如相同数值的2字节,在中文和日语中则表示两个不同的字符。这些不同国家的字符集,同样也被微软纳入了代码页体系中,例如中文就是第936页代码页(我们最常见的CP936就是这个意思,它表达的字符集和GBK是一样的)。

Windows支持4种不同的双字节字符集:代码页932(日文)、936(简体中文)、949(韩文)以及950(繁体中文)。在双字节字符集中,一个字符串中的每个字符都由1字节或2字节组成。以日文为例,如果第1字节在0x81~0x9F或0xE0~0xFC,就必须检查下一字节,才能判断出一个完整的字符。对程序员而言,和双字节字符集打交道如同一场噩梦,因为有的字符是1字节宽,有的字符却是2字节宽。 

Unicode国际化

为了表示不同国家和地区的语言,编码方案有上百种,避免这种混乱的需求由来已久。Unicode是1988年由Apple和Xerox共同建立的一项标准,Unicode的诞生解决了双字节字符集的混乱问题。虽然同样是用16位(2字节)来表示字符,但Unicode只有一个字符集,包含了世界上任何一个国家和地区的语言所用的字符。Unicode标准定义了所有主要语言中使用的字母、符号、标点,其中包括了欧洲地区的语言、中东地区的希伯来语言、亚洲地区的语言等。Unicode有3种编码形式,允许字符以字节、字或双字格式存储。

● UTF-8。UTF-8将有的字符编码为1字节,有的字符编码为2字节,有的字符编码为3字节,甚至有的字符编码为4字节。值在0x80(128)以下的字符(即标准ASCII)被转换为1字节,适合美国;0x80~0x7FF的字符被转换为2字节,适合欧洲和中东地区;0x800以上的字符被转换为3字节,适合东亚地区;最后,代理对(Surrogate Pair)被转换为4字节。代理对是UTF-16中用于扩展字符而使用的编码方式,采用4字节(两个UTF-16编码)来表示一个字符。UTF-8是一种相当流行的编码格式,但在对值为0x800以上的大量字符进行编码时,UTF-8不如UTF-16高效。

● UTF-16。UTF-16将每个字符编码为2字节(16位)。在谈到Unicode时,除非专门声明,一般都是指UTF-16编码。Windows之所以使用UTF-16,是因为全球各地使用的大部分语言中,通常用一个16位值来表示每个字符,每个字符被编码为2字节,所以很容易遍历字符串并计算它的字符个数。但是,16位不足以表示某些语言的所有字符。对于不能表示的字符,UTF-16支持使用代理对,代理对是用32位(4字节)来表示一个字符的一种方式,由于只有少数应用程序需要使用这类字符,因此UTF-16在节省空间和简化编码这两个目标之间提供了一个很好的折衷。

● UTF-32。UTF-32将每个字符都编码为4字节,用于不太关心存储空间的环境中。在将字符串保存到文件或传输到网络的时候,基于空间和速度的考虑,很少会使用这种格式,这种编码格式一般在应用程序内部使用。把长度较小的Unicode值(例如字节)复制到长度较大的Unicode值(例如字或双字)中不会丢失任何数据。另外,Unicode的实现还有大小端(后面会讲)存储的区别,并且UTF-8还存在是否带有BOM标记的问题,因此在很多文本编辑器里有多种关于Unicode这一项的编码转换。

ASCII和ANSI

首先是字面上的差别,ASCII即American Standard Code for Information Interchange,美国信息互换标准代码;ANSI即American National Standard Institite,美国国家标准协会的一种编码标准。后者更强调国家标准,一般是面向世界范围内国家和地区之间的交流,该协会规定了很多类似的标准。为了让计算机支持更多语言,值在0x80~0xFFFF范围的字符使用2字节或多字节来表示,比如:汉字“中”在中文操作系统中使用[0xD6,0xD0]来存储。不同的国家和地区制定了不同的标准,由此产生了GB2312、GBK、GB18030、Big5、Shift_JIS等各自的编码标准。这些使用多字节来代表一个字符的各种延伸编码方式,称为ANSI编码。在简体中文Windows操作系统中,ANSI编码代表GBK编码;在繁体中文Windows操作系统中,ANSI编码代表Big5;在日文Windows操作系统中,ANSI编码代表Shift_JIS编码。不同的ANSI编码互不兼容。 当信息在国际间交流时,两种语言的文字无法使用同一个ANSI编码,ANSI编码就是一个具体国家的多字节字符集。ANSI编码表示英文字符时使用1字节,表示中文时用2~4字节。

其次,一般会拿ANSI码和Unicode码对比,两者都是各种语言的表示方法。不同的是,ANSI在不同国家和地区的不同语言中有不同的具体标准,是国家标准,比如,在简体中文系统中就是GB2312、GBK。相对而言,Unicode正如其名,是Universal Code,具有统一、通用的意思,是国际化标准。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值