Windows下的字符串处理(1)

最近感觉Windows下的字符串处理有点紊乱,准备系统学习下。在此做点笔记。

Unicode或者宽字符都没有改变char数据型态在C中的含义。char继续表示1个字节的储存空间,sizeof (char)继续返回1。

理论上,C中1个字节可比8位长,但对我们大多数人来说,1个字节(也就是1个char)是8位宽。

C中的宽字符基于wchar_t数据型态,它在几个表头文件包括WCHAR.H中都有定义,像这
样:
typedef unsigned short wchar_t ;
因此,wchar_t数据型态与无符号短整数型态相同,都是16位宽。

wchar_t c = 'A' ;
变量c是一个双字节值0x0041,是Unicode表示的字母A。(然而,因为Intel微处理器从最
小的字节开始储存多字节数值,该字节实际上是以0x41、0x00的顺序保存在内存中。如果
检查Unicode文字的计算机储存应注意这一点。)

还可以用下面的语句定义宽字符数组:
static wchar_t a[] = L"Hello!"
该字符串也需要14个字节的储存空间,sizeof (a) 将返回14。索引数组a可得到单独的字符。
a[1] 的值是宽字符「e」,或者0x0065。


----------------------------------------------

char * pc = "Hello!" ;
我们可以调用
iLength = strlen (pc) ;
这时变量iLength将等于6,也就是字符串中的字符数。

wchar_t * pw = L"Hello!" ;
再次调用strlen :
iLength = strlen (pw) ;

首先一条警告,继续执行结果是1.

原因:

字符串「Hello!」中的6个字符占用16位:
0x0048 0x0065 0x006C 0x006C 0x006F 0x0021
Intel处理器在内存中将其存为:
48 00 65 00 6C 00 6C 00 6F 00 21 00
假定strlen函数正试图得到一个字符串的长度,并把第1个字节作为字符开始计数,但接着
假定如果下一个字节是0,则表示字符串结束。
这个小练习清楚地说明了C语言本身和执行时期链接库函数之间的区别。编译器将字符串
L"Hello!" 解释为一组16位短整数型态数据,并将其保存在wchar_t数组中。编译器还处理

数组索引和sizeof操作符,因此这些都能正常工作,但在连结时才添加执行时期链接库函数,

例如strlen。这些函数认为字符串由单字节字符组成。遇到宽字符串时,函数就不像我们所
希望那样执行了。

所以提出了wcslen、wprintf等宽字符版的库函数。但是这样写通用性就差了,所以又提出了

_tcslen、TCHAR。那么在书写字符串时为了通用,提出了_T(x)宏。

如果定义了_UNICODE标识符,那么一个称作__T的
宏就定义如下:
#define __T(x) L##x
这是相当晦涩的语法,但合乎ANSI C标准的前置处理器规范。那一对井字号称为「粘贴符
号(token paste)」,它将字母L添加到宏参数上。因此,如果宏参数是"Hello!",则L##x
就是L"Hello!"。
如果没有定义_UNICODE标识符,则__T宏只简单地定义如下:
#define __T(x) x
此外,还有两个宏与__T定义相同:
#define _T(x)__T(x)
#define _TEXT(x)__T(x)
在Win32 console程序中使用哪个宏,取决于您喜欢简洁还是详细。基本地,必须按下述
方法在_T或_TEXT宏内定义字符串文字:
_TEXT ("Hello!")
这样做的话,如果定义了_UNICODE,那么该串将解释为宽字符的组合,否则解释为8位的
字符字符串。


---------------------------------------

宽字符和 Windows

WINNT.H定义了新的数据型态,称作CHAR和WCHAR:
typedef char CHAR ;
typedef wchar_t WCHAR ; // wc


WINNT.H表头文件进而定义了可用做8位字符串指针的六种数据型态和四个可用做const
8位字符串指针的数据型态。这里精选了表头文件中一些实用的说明数据型态语句:
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定义了六种可作为16位字符串指针的数据型态和四种可作为const 16
位字符串指针的数据型态:
typedef WCHAR * PWCHAR, * LPWCH, * PWCH, * NWPSTR, * LPWSTR, * PWSTR ;
typedef CONST WCHAR * LPCWCH, * PCWCH, * LPCWSTR, * PCWSTR ;
至此,我们有了数据型态CHAR(一个8位的char)和WCHAR(一个16位的wchar_t),
以及指向CHAR和WCHAR的指标。与TCHAR.H一样,WINNT.H将TCHAR定义为一般的
字符类型。如果定义了标识符UNICODE(没有底线),则TCHAR和指向TCHAR的指标就
分别定义为WCHAR和指向WCHAR的指标;如果没有定义标识符UNICODE,则TCHAR
和指向TCHAR的指标就分别定义为char和指向char的指标:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章