字符和字符串处理

ASCII标准

ASCII美国信息交换标准码起始于50年代后期,并最终在1967年定案。开发ASCII的过程中,在代码位宽是6位、7位还是8位的问题上产生了很大的争议。从可靠性的观点看,不应该使用转换字符,因此ASCII不能是6位编码,而且由于费用的原因也排除了8位的版本方案(当时每位的价格很昂贵)。这样最终的代码就是26个小写字母、26个大写字母、10个数字、32个符号、33个控制代码和一个空格,总共128个代码。ASCII现在记录在ANSI X3.4-1986,代码字符集——用于信息交换的7位美国国家标准代码,由美国国家标准协会(ANSI)发布。

 

扩展ASCII

基于ANSI草案和ISO标准,纯Windows字符集被称为“ANSI”字符集。ANSI草案和ISO标准最终成为ANSI/ISO8859-1-1987,即“American NationalStandard for Information Processing ——8 Bit Single-Byte CodedGraphic Character Sets”。

MS-DOS 3.3(1987年4月发行)向IBN PC用户引进了代码页(Code Page)的概念,Windows也使用此概念。代码页定义了字符的映射代码,它其实就是字符集编码的别名,也有人称它为"内码表"。

 

双字节字符集

扩展ASCII后,字符集的字符个数从128个达到了256个,但是中国、日本和朝鲜/韩国的象形文字符号大约有21000个。如何容纳这些语言而依然保持和ASCII的某种兼容性呢?

解决方案是双字节字符集(DBCS:double-byte character set)。最初的128个代码是ASCII,然而较高的128个代码中的某些总是跟随着第二个字节,这两个字节一起定义一个字符,通常是一个复杂的象形文字。这就引起了一个问题,双字节字符集并不是说字符由两个字节代表,一个双字节字符集的字符串中,一个字符都由1个或2个字节组成。对程序员而言,和双字节打交道如同一场噩梦,因为某些字符是1个字节宽,而有些字符却是2个字节宽。字符串中的字符数不能由字符串的字节数确定。必须剖析字符串来决定其长度,而且必须检查每个字节以确定它是否为双字节字符的首字节。

 

Unicode解决方案

Unicode采用16位编码方式,这样就允许表示65535个字符。这对所有字符及世界上使用象形文字的语言,包括一系列的数学、符号和货币集合来说都是充裕的。

 

Unicode与DBCS之间的区别:Unicode是“宽字符集”,每个字符都是16位宽。在Unicode中,8位数值没有意义。相比之下,DBCS依然可以处理8位数值。有些字节自身定义一个字符,而有些字节则需要和另一个字节共同定义一个字符。

 

UTF

UTF的全称是Unicode TransformationFormatUnicode转换格式)。

 

UTF-16

UTF-16将每个字符编码为2个字节(或者说是16位),一般谈到Unicode编码都是指的UTF-16编码。.NETFramework始终使用UTF-16来编码所有字符和字符串,所以在开发的Windows应用程序中,如果需要在本机代码(nativecode)和托管代码(managed code)之间传递字符或字符串,使用UTF-16能改进性能和减少内存消耗。

 

UTF-8

UTF-8将一些字符串编码为1字节,一些字符编码为2字节,一些字符编码为3字节,一些字符编码为4字节。UTF-8是一种流行的编码格式,用在网页上可以同一页面显示中文简体繁体及其它语言(如日文,韩文)。

 

字符串处理

C中的宽字符基于wchar_t数据类型。

typedef  unsignedshort  wchar_t;

除此之外,WinNT.h头文件还定义了一系列能为我们提供大量方便的数据类型。

维护单一源码

使用TCHAR.h头文件可以既能按ASCII编译又能按Unicode编译。该头文件不是ANSI C标准的一部分,因此那里定义的每个函数和宏定义的前面都有一条下划线。这里说明一下UNICODE_UNICODE标识符的区别_UNICODEC运行库定义的标识,针对不属于C++标准的一部分标识,C运行库始终会为它们附加下划线前缀。但是Windows团队并没有这么做,而是在WINNT.h中定义UNICODE标识符来区分普通字符和宽字符的相关定义。所以建议Windows应用程序中,应确保要么同时定义UNICODE_UNICODE,要么一个都不定义。

 

推荐的字符和字符串处理方式

用通用数据类型(如TCHAR/PTSTR)来表示文本字符和文本字符串。

用明确的数据类型(如BYTE和PBYTE)来表示字节、字节指针和数据缓冲区。

用TEXT或_T宏来表示字面量字符和字符串,但为了保持一致性和更好的可读性,避免两者混用。

修改于字符串有关的计算。例如,函数经常希望我们传给它缓冲区大小的字符数,而不是字节数。这意味着我们应该传入_countof(szBuffer),而不是sizeof(szBuffer)

避免使用printf系列函数。使用MultiByteToWideCharWideCharToMultiByte函数进行Unicode与ANSI之间的转换。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值