常见的英文字符,数字,以及标点符号。用一个字节表示,一共可表示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