C中的宽字符定义如下:
typedef unsigned short wchar_t;
因此wchar_t数据类型与无符号短整型相同,都是16位宽。
可以这样定义:
Wchar_t c = L”A”; // 前面的大写字母L是long的意思。
字符串”Hello!”占用16:
0x0048 0x0065 0x006c 0x006c 0x006f 0x0021
Intel处理器在内存中占用的内存:
48 00 65 00 6c 00 6c 00 6f 00 21 00
strlen的宽字符版本是wcslen。在STRING.H和WCHAR.H中均有声明。
strlen函数声明如下:
size_t __cdecl strlen(const char *);
wcslen的函数声明如下:
size_t __cdecl wcslen(const wchar_t *);
printf的宽字符版本是wprintf。这些函数在WCHAR.H和含有标准函数声明的头文件中声明。
使用Unicode也有缺点。第一点:程序中的每个字符串都将占用两倍的存储空间。此外,宽字符运行库中的函数比常规的函数大。出于这个原因,也许想要建立两个版本的程序——一个处理ASCII字符串,另一个处理Unicode字符串。最好的解决办法是维护既能按ASCII编译又能按Unicode编译的单一源代码文件。
虽然只是一个小问题,但由于运行库函数有不同的名称,也要用不同的方式定义字符这将在处理前面有L的字符串文字是遇到麻烦。
一个办法是使用Microsoft Visual C++包含的TCHAR.H头文件。改头文件不是ASCI C标准的一部分,因此那里定义的每个函数和宏定义的前面都有一条下划线。TCHAR.H为需要字符串参数的标准运行库函数提供一系列的替代名称(例如,_tprintf和_tcslen)。有时这些名称也成为“通用”函数名,因为它们既可以指向函数的Unicode版也可以指向非Unicode版。
如果定义了_UNICODE的标识符,并且程序中包含了TCHAR.H头文件,那么_tcslen定义为wcslen:
#define _tcslen wcslen
如果没有定义UNICODE则_tcslen定义为strlen:
#define _tcslen strlen
TCHAR.H还有一个新的数据类型TCHAR来解决两种数据类型的问题。
#ifdef _UNICODE
#define wchar_t TCHAR
#else
#define char TCHAR
#endif
现在讨论字符串文字中的L问题。
#ifdef _UNICODE
#define __T(x) L##x
#else
#define __T(x) x
#endif
这是属于C预处理的ANSI C标准。这一对##称为“粘贴符号(token paste)”,它将字母L添加到宏参数上。如果宏参数是”Hello!”,则L##x就是L”Hello!”。
此外还有两个宏定义_T(x)
#define _T(x) __T(x)
#define _TEXT(x) __T(x)
在Win32控制台程序中使用哪个宏,取决于喜欢简洁还是详细。基本上必须按下述方法在_T或_TEXT宏中定义字符串文字:
_TEXT(“Hello!”)
WINNT.H头文件定义了可用作8位字符串指针的6种数据类型和4个可用作const8位字符串指针的数据类型。精选的一些使用的说明数据类型的语句:
typedef CHAR * PCHAR, * LPCH, * PCH, * NPSTR, * LPSTR, * PSTR;
typedef CONST CHAR * LPCCH, * PCCH, * LPCSTR, * PCSTR;
前缀N和L表示“near”和“long”,指的是16位Windows中两种不同大小的指针。在Win32中near和long指针没有区别。
WINNT.H文件中定义了6种可作为16位字符串指针的数据类型和4种可作为const16位字符串指针的数据类型:
typedef WCHAR * PWCHAR, * LPWCH, *PWCH, * NWPSTR, * LPWSTR, * PWSTR;
typedef CONST WCHAR * LPCWCH, * PCWCH, * LPCWSTR, * PCWSTR;
#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
WINNT.H头文件还定义了一个宏,该宏将L添加到字符串的第一个引号前。
#ifdef UNICODE
#define __TEXT(quote) L##quote
#else
#define __TEXT(quote) quote
#endif
此外TEXT宏这样定义:
#definde TEXT(quote) __TEXT(quote)
定义了这些宏可以使我们在同一程序中混合使用ASCII和Unicode字符串、或者编写一个可被ASCII或Unicode编译的程序。如果希望明确定义8位字符变量和字符串,要使用CHAR、PCHAR(或者其他),以及带引号的字符串。为明确地使用16位字符变量和字符串,要使用WCHAR、PWCHAR,并将L添加到引号前面。对于是8位还是16位取决于UNICODE标识符的定义的变量或字符串,要使用TCHAR、PTCHAR和TEXT宏。
Windows中的字符串函数:
lLength = lstrlen(pString);
pString = lstrcpy(pString1, pString2);
pString = lstrcpyn(pString1, pString2, iCount);
pString = lstrcat(pString1, pString2);
iComp = lstrcmp(pString1, pString2);
iComp = lstrcmpi(pString1, pString2);
这些函数与C库中对应的函数功能相同。如果定义了UNICODE标识符,那么这些函数将接受宽字符串,否则只接受常规字符串。宽字符串版本的lstrlenW函数可在Windows98中运行。