Windows 支持标准的 8 位字符 (char 或 CHAR 类型) 以及 16 位字符 (WCHAR, 它被定义为 C 中的 wchar_c 类型)。
WCHAR 是 16 位的 Unicode 字符。它定义在 WinNT.h 中:
[C++] 纯文本查看 复制代码
typedef wchar_t WCHAR; // wc, 16-bit UNICODE character
而上面的 wchar_t 类型定义在 crtdefs.h 中,它通过 WinNT.h 包含 ctype.h 然后再包含的 crtdefs.h 中找到,定义如下:
[C++] 纯文本查看 复制代码 #ifndef _WCHAR_T_DEFINED
typedef unsigned short wchar_t;
#define _WCHAR_T_DEFINED
#endif
因此 wchar_t 在 Windows 里是 16 位,这也可以通过打印 sizeof(wchar_t) 来查看。但在 GNU 中,这个类型是 32 位的,使用该类型时需要包含 stddef.h 头文件。
Windows 提供的宽字符支持使用 Unicode UTF-16 编码,它可以表示所有主要语言符号问字母,包括英语,法语,德语,汉语及日语等。
如果希望编写的 Windows 应用程序能够支持使用 Unicode 也能够支持使用 8 位 ASCII 字符,一般步骤如下:
1) 使用通用类型 TCHAR,LPTSTR 和 LPCTSTR 来定义所有的字符和字符串。
2) 如果要使用 Unicode 宽字符 (ANSI C 中的 wchar_t),那么需要在所有原模块中加入:
[C++] 纯文本查看 复制代码 #define UNICODE
#define _UNICODE
定义。否则,TCHAR 就等同于 CHAR (也就是使用 8 位 ASCII,即 ANSI C 中的 char 类型)。上面定义必须在 #include <windows.h> 语句之前给出,它们往往会在编译时在命令行里给出,或者就写在用 Visual Studio 里新建项目时所包含的 stdafx.h 头文件里。
所以,在步骤 1) 中的 TCHAR 在 UNICODE 定义的情况下就是一个 WCHAR 类型,否则就是 CHAR 。TCHAR 定义在 WinNT.h 中,如下所示:
[C++] 纯文本查看 复制代码
#ifdef UNICODE
typedef WCHAR TCHAR;
#else
typedef char TCHAR;
#endif
3) 缓存长度字节数。
比如在函数 ReadFile() 函数中的第 2 个参数是一个缓存指针,这个指针指向一个缓存区域,而这片区域的长度可以通过 sizeof(TCHAR) 来计算。
4) 使用 tchar.h 中的通用 C 库字符串和字符 I/O 函数集。比如在 tchar.h 中,会使用 _sprintf 来替代 sprintf,_tcscpy 来替代 strcpy 等等。
5) 字符串常量使用下面 3 种形式的一种来定义(这些约定也可以用于单个字符上):
[C++] 纯文本查看 复制代码
"hello world" //这个字符串使用的是 8 位字符
L "hello world" //在字符串前面加个 'L' 表示这个字符串使用 16 位字符
_T "hello world" //这个字符串使用通用文本字符
上面 3 种形式中,前面 2 种是 ANSI C 的,第 3 种使用 _T 宏 (等同于 TEXT 和 _TEXT) 由 Microsoft C 编译器提供。
6) 在包含了 windows.h 之后,再将 tchar.h 包含进来,可以获得所需的文本宏和通用的 C 库函数的定义。
总之,Windows 全面使用 Unicode 16 位字符,NTFS 文件名和路径名在内部都以 Unicode 来表示。如果定义了 UNICODE 宏,那么调用 Windows 函数就需要宽字符字符串,否则要把 8 位字符串转换为宽字符串。有些 Windows API 只支持 Unicode 。 |