windows中的字符集主要包括以下几种ASCII,MBCS,UNICODE,UTF-8,GB2312等几种,这几种字符集的详细说明如下
1)ASCII码,即“美国国家标准资讯交换码”(AmericanStandard Code For International Interchange)的缩写。
ASCII表上的数字 0~31 分配给了控制字符
数字 32~126 (127表示删除键)分配给了能在键盘上的可见字符
2)MBCS(多字节字符集)
在多字节字符集下,字符被编码为单字节或双字节 。在双字节字符中,第一个字节表示它和下一个字节将被解释为一个字符。第一个字节作为双字节的代码范围 。
3)UNICODE字符集
UNICODE字符集使用双字节编码,可以表示所有语言的字符。UNICODE字符集用一个16位(两字节)来表示每个字符,因此总共可以得到65000多个字符,能够对世界各国的书面文字中的所有字符进行编码。
4)UTF-8字符集
UTF-8字符集兼容ASCII编码,同时也可以用来表示所有语言的字符。UTF-8编码是不定长编码,每一个字符的长度从1到4个字节不等。在传输和存储英文内容较多的数据时,使用UTF-8字符集编码的内容更便于传输和存储。
5)GB2312/GBK字符集
GB2312字符集是中华人民共和国国家汉字信息交换用编码,全称《信息交换用汉字编码字符集——基本集》。
关于这些字符集的概念,我们只需要了解就好,在我们平时编程中,尤其是win32编程中,我们主要需要注意的就是,宽窄字符集,在win32中,窄字符集带表的是ASCII码,宽字符集一般来说代表的是UNICODE字符集。在C++中,我们这样定义一个窄字符
char str='A';
char* pStr="hello";
而定义一个宽字符集是这样的
wchar_t str='A';
wchar_t pStr=L"hello";
相应的,C++中,字符串函数同样也有两套
char * strchr(const char *,int);
wchar_t * wcschr(const wchar_t *,wchar_t);
int strcmp(const char *,const char *);
int wcscmp(const wchar_t *,const wchar_t *);
char * strcpy(char *,const char *);
wchar_t * wcscpy(wchar_t *,const wchar_t *);
size_t strlen(const char *);
size_t wcslen(const wchar_t *);
这两套函数必须对应相应的字符集,如果用错,编译器并不会报错,但是会产生严重的后果,实际开发中,字符集是一个很重要的要注意的事项,否则产生bug很难排查
Windows从底层支持Unicode。Windows可执行为ASCII、Unicode或者ASCII和Unicode混合编写的,一个Windows程序必须包括WINDOWS.H头文件。该头文件包括许多其他头文件,包括WINDEF.H,该文件中定义了Windows编程中使用到的基本数据类型,而且它本身也包括WINNT.H,WINNT.H提供了对Unicode支持。
WINNT.H定义了新的数据类型:CHAR和WCHAR
typedef char CHAR ;
typedef wchar_t WCHAR ;
WINNT.H头文件中定义了可用做单字节字符串指针的6种变量类型和用做constchar*指针的4种变量类型定义
typedef CHAR * PCHAR, * LPCH, * PCH, * NPSTR, * LPSTR, * PSTR ;
typedef CONST CHAR * LPCCH, * PCCH, * LPCSTR, * PCSTR ;
WINNT.H定义了6种可作为双字节字符指针数据类型和用做constWCHAR*指针的4种变量类型定义
typedef WCHAR * PWCHAR, * LPWCH, * PWCH, * NWPSTR, * LPWSTR, * PWSTR ;
typedef CONST WCHAR * LPCWCH, * PCWCH, * LPCWSTR, * PCWSTR ;
windows 还定义了一个宏,TEXT宏,它的作用就是自己识别字符串需要的类型,然后自适应比如我们前面win32那篇博客里有一行代码
wc.lpszClassName = TEXT("Linimass");
用这个宏,它会自动检测需要给那种字符集
在编写代码的过程中尽量遵循下面的规则:
1)将文本串视为字符数组,而不是char 数组或字节数组。
2)将通用数据类型(如TCHAR和PTSTR)用于文本字符和字符串。
3)将显式数据类型(如BYTE和PBYTE)用于字节、字节指针和数据缓存。
4)将_T E X T或者_T 宏用于定义字符和字符串。
5)执行全局性替换,例如用PTSTR替换PSTR。
所以实际开发时,我们通常会做如下的事情
#ifdef UNICODE
#define string wstring
#define STRRCHR wcsrchr
#define MEMCPY wmemcpy
#define strTcat wcscat_s
#else
#define string string
#define STRRCHR strrchr
#define MEMCPY memcpy
#define strTcat strcat_s
#endif
我们会将用到的涉及到字符集的数据类型,字符串函数来个重定义,让他可以自适用,当然,具体重定义什么要看实际需要,我这只是把我某个项目用到的贴了出来,大家根据需求重新定义
进行Windows应用程序开发时,可以根据需要选择使用MBCS还是UNICODE字符集,在“属性页”对话框中,选择“配置属性”的“常规”属性页,可以设置当前应用程序使用哪种字符集
Windows函数MultiByteToWideChar用于将多字节字符串转换成宽字节字符串。
int MultiByteToWideChar(
UINT //uCodePage,
DWORD //dwFlags,
LPCSTR //lpMultiByteStr,
int //cchMultiByte,
LPWSTR //lpWideCharStr,
int //cchWideChar
);