Unicode
背景
以前一直听说过Unicode,认识比较粗浅,我们的汉字是Unicode编码的,但是具体的原因及其用途不是很清楚。以前在写C#程序的时候也没怎么注意该问题对程序有什么影响。最近在做C/C++的项目时,看见项目中许多诸如_T(“hello”);的代码,对_T()不是很了解。 因为在自己以前学习中,不管是C 还是C++里好像都没有这样代码。
ASCII与Unicode
ASCII内容
控制字符:回车键、退格、换行键等。
可显示字符:英文大小写字符、阿拉伯数字和西文符号
ASCII位数
7位(bits)表示一个字符,共128字符,字符值从0到127,其中32到127是可打印字符。扩展字符集
7位编码的字符集只能支持128个字符,为了表示更多的欧洲常用字符对ASCII进行了扩展,ASCII扩展字符集使用8位(bits)表示一个字符,共256字符。
UNICODE字符集
作用:为世界650种语言进行统一编码。
位数:UNICODE字符集有多个编码方式,分别是UTF-8,UTF-16和UTF-32。
作用:为世界650种语言进行统一编码。
位数:UNICODE字符集有多个编码方式,分别是UTF-8,UTF-16和UTF-32。
windows编程中的字符
普通字符char为C基本类型,以8位表示
宽字符wchar_t 在WCHAR.h中定义为 typedef unsigned short wchar_t ; 无符号短整型 16位表示
1 int _tmain(int argc, _TCHAR* argv[]) 2 { 3 4 char s1[]="hello!"; 5 int size1=sizeof(s1); //7 6 int length1=strlen(s1); //6 7 8 wchar_t ws[]=L"Hello!"; 9 int size2=sizeof(ws); //14 10 // int l2=strlen(ws);//错误 1 error C2664: “strlen”: 不能将参数 1 从“wchar_t [7]”转换为“const char *” e:\xx\xx\xx\test.cpp 18 11 12 int length2=wcslen(ws); //6 13 14 return 0; 15 }
WINNT.H 定义了新的资料型态,称作CHAR 和WCHAR
typedef char CHAR ; typedef wchar_t WCHAR ;
关于普通8位字符类型的其他新类型定义
typedef CHAR * PCHAR, * LPCH, * PCH, * NPSTR, * LPSTR, * PSTR ;
typedef CONST CHAR * LPCCH, * PCCH, * LPCSTR, * PCSTR ;
关于16位宽字符类型的其他新类型定义
typedef WCHAR * PWCHAR, * LPWCH, * PWCH, * NWPSTR, * LPWSTR, * PWSTR ;
typedef CONST WCHAR * LPCWCH, * PCWCH, * LPCWSTR, * PCWSTR ;
至此,我们有了资料型态CHAR(一个8 位的char)和WCHAR(一个16 位的wchar_t),以及指向CHAR 和WCHAR的指标。
与TCHAR.H 一样,WINNT.H将TCHAR定义为一般的字元类型。
#ifdef UNICODE typedef WCHAR TCHAR, * PTCHAR ; typedef LPWSTR LPTCH, PTCH, PTSTR, LPTSTR ; typedef LPCWSTR LPCTSTR ; #else typedef char TCHAR, * PTCHAR ; typedef LPSTR LPTCH, PTCH, PTSTR, LPTSTR ; typedef LPCSTR LPCTSTR ; #endif
这里为什么要将这么多的类型定义列举出来呢,主要是自己刚开始接触代码,在代码中看见各种各样的类型,搞不清楚究竟是什么类型,我一直疑惑同一种类型为什么要定义出来这么多相同的新类型呢,增加代码理解难度。
函数
在继续往下看,发现在windows编程中所有函数中若参数中包含字符、字符串的函数都可以分上三种方式处理,如:
CHAR | WCHAR | TCHAR |
strlen | wcslen | _tcslen |
strcmp | wcscmp | _tcscmp |
MessageBoxA | MessageBoxW | MessageBox |
cout | wcout | ? |
c... | w... | _t... |
可以看出在windows基本上所有的字符/字符串处理函数,都提供了三种方式实现,相互对应。c.../w.../_t...
相互转换
WINBASEAPI int WINAPI MultiByteToWideChar( __in UINT CodePage, __in DWORD dwFlags, __in_bcount(cbMultiByte) LPCSTR lpMultiByteStr, __in int cbMultiByte, __out_ecount_opt(cchWideChar) __transfer(lpMultiByteStr) LPWSTR lpWideCharStr, __in int cchWideChar); WINBASEAPI int WINAPI WideCharToMultiByte( __in UINT CodePage, //指定执行转换的代码页 __in DWORD dwFlags, //允许你进行额外的控制,它会影响使用了读音符号(比如重音)的字符 __in_ecount(cchWideChar) LPCWSTR lpWideCharStr, //指定要转换为宽字节字符串的缓冲区 __in int cchWideChar, //指定由参数lpWideCharStr指向的缓冲区的字符个数 __out_bcount_opt(cbMultiByte) __transfer(lpWideCharStr) LPSTR lpMultiByteStr, //指向接收被转换字符串的缓冲区 __in int cbMultiByte, //指定由参数lpMultiByteStr指向的缓冲区最大值 __in_opt LPCSTR lpDefaultChar, //遇到一个不能转换的宽字符,函数便会使用pDefaultChar参数指向的字符 __out_opt LPBOOL lpUsedDefaultChar //至少有一个字符不能转换为其多字节形式,函数就会把这个变量设为TRUE
参考:《Windows程序设计(第五版)》