常见的英文字符,数字,以及标点符号。用一个字节表示,一共可表示 256 个字符,对于使用英文的国家来说已经足够,但是对于像中国, 1 个字节不足以表示所有的字符,所以在 ASCII 的基础上,对其进行拓展,形成了自己的字符集和编码方式。
不同的国家地区制定了不同的标准表示自己的字符,如:
中国大陆: GBK18030
中国台湾: BIG5
日本: SJIS
这些编码统称为 ANSI 编码。在简体中文系统下, ANSI 编码代表的就是 GBK ,而在繁体中文系统下, ANSI 代表的就是 BIG 。 ANSI 对 ASCII 是兼容的,既是不同的 ANSI 编码对 ASCII 字符的码值都是一样的,就是 ASCII 码值。但是不同的 ANSI 编码之间是不兼容的,在 GBK 中这个码值在 BIG 中可能就对应与另外一个字符。对于纯文本来说只有一种编码方式,因此你不能在一个 ANSI 编码的文本中存储不同的语言文字。例如:如果你在 ANSI 编码的文本中既输入简体又输入繁体,那么在简体中文系统中,简体可以正确显示,而繁体则是乱码;相反的,在繁体中文系统中,繁体可以正确显示,而简体则是乱码。为了解决这个问题,就出现了 Unicode 编码。
Unicode ( Universal Multiple-Octet Coded Character Set )采用两个字节对所有的语言进行统一编码。这样就可以在一个 Unicode 编码的文本中存储不同国家的语言文字了。它对 ASCII 码也是兼容的。 Unicode 一共可以表示 65536 个字符,这个够用吗?目前是够用了,应对于将来的可能情况,还有 4 个字节的 Unicode 编码。因此 Unicode 分为 ucs-2 和 ucs-4 编码。
但是 ASCII 字符在 ucs-2 中的编码,是在原来一个字节的前面再加上 0x00 ,这样在 C 语言处理字符的时候,就会把它当成是字符串的结束符‘ /0 ’。因此需要对这个问题进行解决,一个办法就是 wchar_t ,以 0x0000 作为结束符;另外一个办法就是用 UTF ( UCS Transformation Format )来对 Unicode 进行编码。
UTF 是通用字符编码传输格式。根据最小编码单位分为 UTF-8 , UTF-16 , UTF-32 。
UTF-8 将 unicode 码划分为三段,每一段采用不同的编码方法:
0x0000-0x007F 0x0******* 一个字节
0x0080-0x07FF 0x110***** 0x10****** 两个字节
0x0800-0xFFFF 0x1110**** 0x10****** 0x10****** 三个字节
对 windows 文本文件 txt 而言,它利用开头的几个字节来判断:
EF BB BF UTF-8
FE FF UTF-16/UCS-2, little endian
FF FE UTF-16/UCS-2, big endian
FF FE 00 00 UTF-32/UCS-4, little endian.
00 00 FE FF UTF-32/UCS-4, big-endian.
如何把各国编码和 Unicode 之间互相转换?这就需要用到 Codepage ,就是各国编码和 Unicode 之间的转换映射表。常见的有:
codepage=936 简体中文 GBK
codepage=950 繁体中文 BIG5
codepage=437 美国 / 加拿大英语
codepage=932 日文
codepage=949 韩文
codepage=65001 unicode UFT-8
在 VC 工程中,可以设置工程的属性采用的字符集是 MBCS ( Multi-Byte Character Set )还是 Unicode 。其实就是说,程序运行时对字符识别是采用 ANSI 编码还是 ucs-2 编码。因为各国的 ANSI 编码可能是 2 个, 3 个字节等,所以都统称为多字节字符集。当然为了程序的多语言特性,我们最好使用 Unicode ,这样我们就可以显示出多国语言。如果设置工程属性采用 MBCS ,那么只能显示 ASCII 字符和 local 字符(通常就是你的操作系统的语言,但是可以通过 setlocal 函数来设置本地语言)。
因为可能我们的程序采用的字符集可能是 MBCS ,也有可能是 Unicode ,所以我们在程序中对字符串的类型不能固定的声明为 char* 或者是 wchar_t* 类型,这样就不能很好的实现字符集的无关性。而是要使用到 Tchar.h 中定义的类型 _TCHAR ,如果工程采用 MBCS ,则它被定义为 char ;如果采用 Unicode ,则它被定义为 wchar_t 类型。与此类似的,关于字符串的处理函数我们也需要换成 tcs 开头的函数。例如 _tcslen() , _itot() 。
msdn 上对于 _TCHAR 的说明如下:
Preprocessor Directives for Generic-Text Mappings
# define |
Compiled version |
Example |
_UNICODE |
Unicode (wide-character) |
_tcsrev maps to _wcsrev |
_MBCS |
Multibyte-character |
_tcsrev maps to _mbsrev |
None (the default: neither _UNICODE nor _MBCS defined) |
SBCS (ASCII) |
_tcsrev maps to strrev |
Generic-Text Data Type Mappings
Generic-Text Data Type Name |
_UNICODE & _MBCS Not Defined |
_MBCS Defined |
_UNICODE Defined |
_TCHAR |
char |
char |
wchar_t |
_TINT |
int |
int |
wint_t |
_TSCHAR |
signed char |
signed char |
wchar_t |
_TUCHAR |
unsigned char |
unsigned char |
wchar_t |
_TXCHAR |
char |
unsigned char |
wchar_t |
_T or _TEXT |
No effect (removed by preprocessor) |
No effect (removed by preprocessor) |
L (converts following character or string to its Unicode counterpart) |
除此之外的 T 类型还有: LPCTSTR, LPTSTR 等等。
Reference :
【1】 http://bbs.hfutbbs.com/read.php?tid=223267
【2】 http://blog.csdn.net/lesterjames/archive/2005/09/28/491619.aspx
【3】 http://msdn.microsoft.com/zh-cn/library/c426s321(VS.80).aspx
摘自:http://blog.csdn.net/dadalee/archive/2009/03/25/4024695.aspx