概述
对于众多的编码规范一直没有一个清晰的认识,本文旨在理清这些编码规范的定义和特点。
ASCII
ASCII全称是美国国家信息交换标准码,它是用于字符转换的一个标准,长度是7位,可以标记128个不同的字符,但是这个标准极其有限,比如说它就无法支持中文的编码,甚至连其他英语国家的需求也无法满足,比如说英国的英镑符号。
ANSI
ANSI是美国的一家非营利制定国家标准的机构,ANSI也被称为微软的扩展字符集,8位表示,所以它也被称为扩展ASCII,可以填充256个字符,这套标准最终成为ANSI/ISO 8859-1--1987。
各国根据这套标准弄出了自己的编码表,比如著名的GB2312等,它们都统称为ANSI编码集,也叫MBCS(Multi-Byte Character System),这些编码表都是8位,小于128的字符都跟ASCII编码表一样,大于128的字符后面会再跟着一个字节,称作Leading byte,系统判断它是否大于128,如果大于128,就知道它后面还有一个字节,通过这样的编码方式就可以将中文等语言编码进去,但是这样的编码集太多了,在不同国家需要设定不同的编码集,不利于程序的传播,因此需求一个更加有效的统一标准解决这个问题,Unicode就应运而生了。
Unicode
Unicode是16位的,它可以表示的字符数是65535个,因此它涵盖了几乎所有的字符和象形文字,另外还可以包括一些符号等字符。Unicode占16位,因此它也叫UTF-16,后来为了在单字节的系统上顺利使用,出现了UFT-8,它的编码方式跟MBCS差不多。
ANSI C
即ANSI/ISO 9899-1990,它是美国国家标准机构为C语言专门制定的标准。
C语言和宽字符
ANSI C专门为C指定标准,它定义了一个宽字符的概念,使ANSI C标准支持多种用多个字节来表示一个字符的字符集。
C语言中的宽字符是基于wchar_t的。宽字符并不等于Unicode,Unicode只是宽字符的一种表现形式,不过在Windows程序中帮助理解,可以认为宽字符就是Unicode。
C语言宽字符版变量
wchar_t *p = L"Hello";
C语言宽字符版函数
在C语言当中,对于字符的操作函数几乎都有两个版本,比如printf(),对应宽字符版函数是wprintf(),这个函数在传入字符串时需要在前面加上L""。
C语言自适应函数
如果有个需求:一份代码编译成ASCII和Unicode两个版本,如果程序本身大量使用宽字符,可以想象,要编译成ASCII版本,不仅要改编译选项还要修改每个函数,每个字符串,这样的工程量是巨大的,在VC++中,有一个TCHAR.H文件,它并不是ANSI C的一部分,但是它里面的函数解决了这个问题,比如说使用它的_tcslen函数时,在宽字符下它就代表着wcslen,在多字节编码下它就代表strlen,这就解决了函数的适配问题,使用 TEXT("xxx")时,在宽字符下它就代表L"xxx",在多字节下就代表"xxx",这就解决了变量的适配问题。
Windows SDK的字符类型
使用Windows SDK的程序推荐使用特定的类型用来替代C语言中的类型。
|c语言的类型|Windows类型|
|----|-----|
|wchar_t|WCHAR|
|char|CHAR|
|自适应|TCHAR
|...|...|
还有常见的如LPTSTR,L是指”long“的意思,P是指针。
Windows SDK的函数
Windows复制了一部分C运行库函数,Windows的函数有很多,例如字符串处理函数,这些Windows函数都是宽字符和多字节自适应的: