默认情况下,在源代码中声明一个字符串时,C编译器会把字符串中的字符转换成有8为char数据类型构成的一个数组:
//An 8-bit character char c = 'A';
//An array of 99 8-bit character and 8-bit terminating zero char szBuffer[100] = "A String";
Microsoft的C/C++编译器定义了一个内建的数据类型wchar_t , 它表示一个16为的Unicode(UTF-16)字符。声明Unicode字符和字符串的方法如下:
//An 16-bit character wchar_t c = L'A';
//An array of 99 16-bit character and 8-bit terminating zero wchar_t szBuffer[100] = L"A String".
为了与C语言稍微有一些区分,Microsoft开发团队希望定义自己的数据类型。于是他们在Windows头文件WinNT.h中定义了以下数据类型:
typedef char CHAR; //An 8-bit character
typedef wchar_t WCHAR //An 16-bit character
WinNT.h头文件中还定义了一系列能为我们提供大量方便的数据类型,可以用来处理字符指针与字符串指针:
//Pointer to 8-bit character(s)
typedef CHAR* PCHAR
typedef CHAR* PSTR
typedef CONST CHAR* PCSTR
//Pointer to 16-bit character(s)
typedef WCHAR* PWCHAR
typedef WCHAR* PWSTR
typedef CONST WCHAR* PCWSTR
WinNT.h定义了以下数据类型和宏:
#ifdef UNICODE
typedef WCHAR TCHAR, *PTCHAR, PTSTR;
typedef CONST WCHAR* PCTSTR;
#define __TEXT(quote) L##quote
#else
typedef CHAR TCHAR , *PTCHAR, PTSTR;
typedef CONST CHAR* PCTSTR;
#endif
#define TEXT(quote) __TEXT(quote)
利用这些类类型和宏来写代码,无论使用ANSI还是Unicode字符,它都能通过编译。如下所示:
TCHAR c = TEXT('A'); // If UNICODE defined ,a 16-bit character; else an 8-bit character
TCHAR szBuffer[100] = TEXT("A String"); // If UNICODE defined ,an array of 16-bit character; else 8-bit character
如果一个Windows函数的参数列表中哟字符串,则该函数通常有两个版本。例如,一个CreateWindowEx接受Unicode字符串,另一个CreateWindowEx则接受ANSI字符串。
HWND WINAPI CreateWindowExW(......)
HWND WINAPI CreateWindowExA(......)
用Visual Studio 创建一个新的项目的时候,它默认会定义Unicode.
和Windows函数一样,C与行库提供了一系列函数来处理ANSI字符和字符串,并提供了另一系列函数来处理Unicode字符和字符串。如strlen和wcslen。
为了使源代码既能用ASNI编译,又能用Unicode编译,还必须包含TChar.h,该文件定义了以下宏:
#ifdef _UNICODE
#define _tcslen wcslen
#else
#define _tcslen strlen
#endif
默认情况下,在Visual Studio中新建一个C++项目时,已经定义了_UNICODE(就像已经定义了UNICODE一样)。
Microsoft在 StrSafe.h 中定义了新的安全字符串函数,在将一个可写的缓冲区作为参数传递时,必须同时提供它的大小。这个值应该是一个字符数。通过对缓冲区使用 _countof 宏(在stdlib.h中定义),我们很容易计算出这个值。
编写代码前要牢记以下几点:
* 将文本字符串想象为字符的数组,而不是 char 或字节的数组。
* 用通用数据类型(如 TCHAR /PTSTR)表示文本字符和字符串。
* 用明确的数据类型(如BITE 和 PBITE)来表示字节,字节指针和缓冲区。
* 用TEXT或_T宏来表示字面字符和字符串。
* 始终使用安全的字符串处理函数,不如后缀为 _s 的函数,或者前缀为 StringCch 的函数
Unicode 与 ANSI 字符串转换函数:
int MultiByteToWideChar(.....);
int WideCharToMultiByte(.....);