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。
 
 

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
View Code

 参考:《Windows程序设计(第五版)》

    http://baike.baidu.com/view/2083430.htm

    http://baike.baidu.com/view/51987.htm

posted @ 2013-06-26 10:46  haox  阅读(688)  评论(0编辑  收藏  举报