宽字符与Unicode

——————————————————————————————————

宽字符与Unicode学习总结

参考书:《Windows程序设计》《Windows核心编程》

朱铭雷

2010.4.2

——————————————————————————————————

1 什么是Unicode

  Unicode字符是一种宽字符,在Windows CE中只支持UnicodeUnicode(统一码、万国码、单一码)是一种在计算机上使用的字符编码。它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。

2 短字符与宽字符

  短字符如ASCIIASCIIAmerican Standard Code for Information Interchange,美国信息交换标准码),字符长度为8位,也就是一个字节。宽字符如Unicode,字符长度为16位,也就是两个字节。

3 数据型态

  短字符,如:

char c = 'A' ;
char *p = "Hello!" ;
char a[] = "Hello!" ;

  宽字符基于wchar_t数据型态,它的定义如下:

typedef unsigned short wchar_t ;
因此,wchar_t数据型态与无符号短整数型态相同,都是16位宽。
wchar_t c = 'A' ;
wchar_t c = L'A' ;
wchar_t *p = L"Hello!" ;
static wchar_t a[] = L"Hello!" ;
  其中L告知编译器需要将字符串存为每个字符2个字节。
4 获取字符串长度
  短字符,如  

int iLength;

char *pc = "Hello!";

iLength = strlen(pc);

TRACE(L"pc iLength = %d/n",iLength);

  宽字符,如

int iLength;

wchar_t *pw = L"Hello!";

iLength = wcslen(pw);

TRACE(L"pw iLength = %d/n",iLength);

即:strlen函数的宽字符版是wcslenwide-character string length:宽字符串长度)。

5        _tcslen  TCHAR  WCHAR  _ T() TEXT()

在编写Windows CE应用程序的时候,可能会用到如上几个函数,数据类型,或者宏。

看了下面的定义,它们的用途也就一目了然了。

_tcslentchar.h文件中定义:

#ifdef  UNICODE

#define _tcslen     wcslen

#else

#define _tcslen     strlen

#endif  /* UNICODE */

  WCHAR TCHARwinnt.h文件中定义:

#ifdef  UNICODE  

typedef WCHAR TCHAR, *PTCHAR;

#else

typedef char TCHAR, *PTCHAR;

#endif /* UNICODE */  

其中:typedef wchar_t WCHAR;    // wc,   16-bit UNICODE character

 _ T() TEXT()定义如下:

#define _T(x)       __TEXT(x)

#define TEXT(quote) __TEXT(quote)

#define __TEXT(quote) L##quote 

双井号称为「粘贴符号(token paste)」,如果宏参数是"Hello!",则L##x就是L"Hello!"

6 标准的ANSI C字符串函数和它们的等价Unicode函数

ANSI string functions

char * __cdecl strcat(char *, const char *);

_CRTIMP char * __cdecl strchr(const char *, int);

int    __cdecl strcmp(const char *, const char *);

char * __cdecl strcpy(char *, const char *);

size_t __cdecl strlen(const char *);

与之对应:

Widechar string functions

_INTRIMP wchar_t * __cdecl wcscat(wchar_t *, const wchar_t *);

_CRTIMP wchar_t * __cdecl wcschr(const wchar_t *, wchar_t);

_INTRIMP int       __cdecl wcscmp(const wchar_t *, const wchar_t *);

_INTRIMP wchar_t * __cdecl wcscpy(wchar_t *, const wchar_t *);

_INTRIMP size_t    __cdecl wcslen(const wchar_t *);

请注意,所有的Unicode函数均以wcs开头,wcs是宽字符串的英文缩写。若要调用Unicode函数,只需用前缀wcs来取代ANSI字符串函数的前缀str即可。

7 UnicodeANSI之间转换字符串

函数MultiByteToWideChar用于将多字节字符串转换成宽字符串。

Sint MultiByteToWideChar(

  UINT CodePage,

  DWORD dwFlags,

  LPCSTR lpMultiByteStr,

  int cbMultiByte,

  LPWSTR lpWideCharStr,

  int cchWideChar

);

  CodePage参数用于标识一个与多字节字符串相关的代码页号。dwFlags参数用于设定另一个控件,它可以用重音符号之类的区分标记来影响字符。这些标志通常并不使用,在dwFlags参数中传递0lpMultiByteStr参数用于设定要转换的字符串,cbMultiByte参数用于指明该字符串的长度(按字节计算)。如果为cbMultiByte参数传递- 1,那么该函数用于确定源字符串的长度。转换后产生的Unicode版本字符串将被写入内存中的缓存,其地址由lpWideCharStr参数指

定。必须在cchWideChar参数中设定该缓存的最大值(以字符为计量单位)。如果调用MultiByteToWideChar,给cchWideChar参数传递0,那么该参数将不执行字符串的转换,而是返回为使转换取得成功所需要的缓存的值。一般来说,可以通过下列步骤将多字节字符串转换成Unicode等价字符串:

1) 调用MultiByteToWideChar函数,为lpWideCharStr参数传递NULL,为cchWideChar参数传递0

2) 分配足够的内存块,用于存放转换后的Unicode字符串。该内存块的大小由前面对MultiByteToWideChar的调用返回。

3) 再次调用MultiByteToWideChar,这次将缓存的地址作为lpWideCharStr参数来传递,并传递第一次调用MultiByteToWideChar时返回的缓存大小,作为cchWideChar参数。

4). 使用转换后的字符串。

5) 释放Unicode字符串占用的内存块。

函数WideCharToMultiByte将宽字符串转换成等价的多字节字符串:

int WideCharToMultiByte(

  UINT CodePage,

  DWORD dwFlags,

  LPCWSTR lpWideCharStr,

  int cchWideChar,

  LPSTR lpMultiByteStr,

  int cbMultiByte,

  LPCSTR lpDefaultChar,

  LPBOOL lpUsedDefaultChar

);

该函数与MultiByteToWideChar函数相似。同样,CodePage参数用于标识与新转换的字符串相关的代码页。dwFlags则设定用于转换的其他控件。这些标志能够作用于带有区分符号的字符和系统不能转换的字符。通常不需要为字符串的转换而拥有这种程度的控制手段,你将为dwFlags参数传递0lpWideCharStr参数用于设定要转换的字符串的内存地址,cchWideChar参数用于指明该字符串的长度(用字符数来计量)。如果你为cchWideChar参数传递- 1,那么该函数用于确定源字符串的长度。

转换产生的多字节版本的字符串被写入由lpMultiByteStr参数指明的缓存。必须在cbMultiByte参数中设定该缓存的最大值(用字节来计量)。如果传递0作为WideCharToMultiByte函数的cbMultiByte参数,那么该函数将返回目标缓存需要的大小值。通常可以使用将多字节字符串转换成宽字节字符串时介绍的一系列类似的事件,将宽字节字符串转换成多字节字符串。

你会发现,WideCharToMultiByte函数接受的参数比MultiByteToWideChar函数要多2个,即lpDefaultCharlpUsedDefaultChar。只有当WideCharToMultiByte函数遇到一个宽字节字符,而该字符在CodePage参数标识的代码页中并没有它的表示法时,WideCharToMultiByte函数才使用这两个参数。如果宽字节字符不能被转换,该函数便使用lpDefaultChar参数指向的字符。如果该参数是NULL(这是大多数情况下的参数值),那么该函数使用系统的默认字符。该默

认字符通常是个问号。这对于文件名来说是危险的,因为问号是个通配符。

lpUsedDefaultChar参数指向一个布尔变量,如果宽字符串中至少有一个字符不能转换成等价多字节字符,那么函数就将该变量置为TRUE。如果所有字符均被成功地转换,那么该函数就将该变量置为FALSE。当函数返回以便检查宽字节字符串是否被成功地转换后,可以测试该变量。同样,通常为该测试传递NULL

 

你可能感兴趣的:(windows,String,null,语言,character,编译器)