目录
1. 什么是Unicode字符&&ANSI字符
2. 字符串数据类型
3. CHAR和WCHAR
4. Windows的Unicode函数和ANSI函数
5. C运行库中的Unicode函数和ANSI函数
Windows编程支持Unicode和ANSI字符,因此其使用的字符类型不像C++或C,只有一种字符类型(即ANSI类型)。所以Windows编程会定义一个宏,根据程序支持何种字符而使用对应字符。
首先简单介绍一下什么是Unicode字符&&ANSI字符,了解的同学可以跳过这part啦~
ANSI字符是指用一个字节即8bit标识一个字符,而Unicode字符是用多个字节标识一个字符,Unicode字符集固定使用16bit标识一个字符,因此其可以标识65536个字符。后来为了双字节的Unicode能够在现存的处理单字节的系统上正确传输,出现了UTF-8,即使用8bit标识一个字符。
ANSI字符 or Unicode字符 | 数据类型 |
ANSI字符 | char |
Unicode字符 | wchar_t |
C语言用char类型标识一个8位ANSI字符,而Windows编程下的C/C++编译器定义了一个内建的数据类型wchar_t,标识一个16位UNICODE(UTF16)字符
wchar_t c = L'A';
wchar_t szBuffer[100] = L"A String";
字符串之前的大写字母L通知编译器该字符串应当编译为一个Unicode字符串(UTF16)。
为了与C语言稍微有一些区分,Windows开发团队希望定义自己的数据类型,因此有了CHAR和WCHAR。于是他们在Windows头文件WinNT.h中定义以下数据类型:
typedef char CHAR; // 一个8bit字符,即ANSI字符
typedef wchar_t WCHAR; // 一个16bit字符,即Unicode字符
// 还定义了一堆指向8bit字符的指针
typedef CHAR *PCHAR; // 其实就是相当于char*
typedef CHAR *PSTR;
typedef CONST CHAR *PCSTR;
// 指向16bit字符的指针
typedef WCHAR *PWCHAR;
typedef WCHAR *PWSTR;
typedef CONST WCHAR *PCWSTR;
Windows开发团队想用自己特有的数据类型,因此出现CHAR等字符类型,这只是在头文件再定义一次而已~类似于起外号花名吧,都是同一个人,不用叫法而已~٩(๑❛ᴗ❛๑)۶
为了写代码方便,可以使用ANSI或Unicode字符通过编译,WinNT.h定义了以下类型和宏:
#ifdef UNICODE
typedef WCHAR TCHAR, * PTCHAR ;
typedef LPWSTR LPTCH, PTCH, PTSTR, LPTSTR ;
typedef LPCWSTR LPCTSTR ;
#define __TEXT(quote) L##quote
#else
typedef char TCHAR, * PTCHAR ;
typedef LPSTR LPTCH, PTCH, PTSTR, LPTSTR ;
typedef LPCSTR LPCTSTR ;
#define __TEXT(quote) quote
#endif
#define TEXT(quote) __TEXT(quote)
emmm,写到这有个感受:头文件#define和typedef太会玩了〒▽〒 对于初学者来说,明明是同一个东西但是有好多个名字,感觉会有点乱~不过后面习惯后就会觉得很方便哒,每一个数据类型都可以顾名思义~
Windows的所有版本都完全用Unicode构建,即若调用Windows函数时,如果向它传入一个ANSI字符串(即由单字节字符组成的一个字符串),函数会先将字符串转换为Unicode,再将结果传给操作系统。
如果一个Windows函数的参数列表中有字符串,则该函数通常有两个版本,eg:一个CreateWindowEx接受Unicode字符串,另一个CreateWindowEx则接受ANSI字符串。但平时我们一般调用CreateWindowEx,这实际就是一个定义的宏
#ifdef UNICODE
#define CreateWindowEx CreateWindowExW
#else
#define CreateWindowEx CreateWindowExA
#endif
C运行库提供了一系列函数来处理ANSI和UNICODE字符和字符串,它和Windows不同的是,函数都是“自力更生”的,如ANSI版本的函数不会把字符串转换为UNICODE形式,再从内部调用函数的UNICODE版本。
eg:strlen是一个能返回ANSI字符串长度的函数,与之对应的是wcslen,其返回的是UNICODE字符串的长度。(原型都在String.h)。为了使源代码既能用ANSI编译,又能用UNICODE编译,还必须包含TChar.h,该文件定义了以下宏:
#ifdef _UNICODE
#define _tcslen wcslen
#else
#define _tcslen strlen
#endif
PS: 针对不属于C++标准一部分的标识符,C运行库始终会为它们附加下划线前缀。
PPS:在应用程序中,应确保同时定义UNICODE和_UNICODE,要么一个都不要定义。
此文只是本人对字符串知识梳理,今天就先到这了~下次get到新的点再更新啦~ヾ(◍°∇°◍)ノ゙