鱼C论坛

 找回密码
 立即注册
查看: 1878|回复: 0

[学习笔记] 《WINDOWS程序设计》(023)2.2 宽字符和C语言-2.2.3 宽字符库函数

[复制链接]
发表于 2018-10-23 14:44:04 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
2.2.3  宽字符库函数

    我们都知道如何找出一个字符串的长度。例如,如果我们定义了一个指向字符串的指针:
    char * pc = “Hello!”;
我们可以调用
    iLength = strlen(pc);
变量iLength会被设成6,也就是字符串中字符的个数。

    好极了!现在让我们尝试定义一个指向宽字符串的指针:
    wchar_t * pw = L”Hello!”;
而且现在我们再次调用strlen:
    iLength = strlen(pw);
现在问题出现了。首先,C编译器会给你一个警告消息,大概是下面这个意思:
‘function’: incompatible types – from ‘unsigned short *’ to ‘const char *’
这是在告诉你strlen函数被定义为接受一个指向char的指针,但这里收到的是一个指向无符号短整型的指针。仍然可以编译运行程序,但你会发现iLength变成了1。发生了什么呢?

    字符串“Hello!”中的6个字符包含的16位值如下:
    0x0048 0x0065 0x006C 0x006C 0x006F 0x0021
这些值被Intel处理器以下面这种方式存储在内存中:
    48 00 65 00 6C 00 6C 00 6F 00 21 00
strlen函数,假设它试图找到字符串的长度,计算第一个字节为字符,但然后会认为第二字节是一个表明字符串结尾的零字节。(找出字符串长度的函数为strlen,但strlen函数被定义为接受一个指向char的指针,如果用这个函数对宽字符串求长度,则会得到不正确的结果。因为ASCII码中字符的高8为0x00,strlen碰到第一个字符的高8位0x00就以为是字符串结束标志,所以得到的结果会是1。【经过在VC6.0++中的调试,结果符合书中所述情况】)

    这个小小的实验清楚地表明了C语言自身和运行库函数的细微差别。编译器将字符串L”Hello!”解释为一个16位短整型的集合并把它们存储在wchar_t数组。编译器还会处理所有数组索引和sizeof操作符,因此这些都会正常工作。但是,程序运行时,运行库函数(如strlen)是在链接时被增加进去的。这些函数期望收到由单字节字符构成的字符串。因此在遇到宽字符时,它们不会像我们预期那样执行。

    你说,哦,太倒霉了,现在每一个C库函数都要被重写,以接受宽字符。嗯,并非每一个C库函数。只有那些有字符串参数的。而且你并不需要重写它们,因为重写已经完成了。

    宽字符版本的strlen函数被称为wcslen(“宽字符字符串长度”),并定义在STRING.H中(也就是strlen被定义的地方)和WCHAR.H中。strlen函数的声明如下:
    _CRTIMP size_t  __cdecl strlen(const char *);
而wcslen函数的声明如下:
    _CRTIMP size_t __cdecl wcslen(const wchar_t *);

    所以现在我们知道了一点:在需要确定一个宽字符的长度时,我们可以调用以下函数:
    iLength = wcslen(pw);
该函数返回的结果是6,也就是字符串中的字符个数。请记住,在使用宽字符的时候,字符串的字符长度并没有改变,改变的只是字节长度。
    【在VC6.0++中的调试结果如下,符合书中所述情况】
001.png
上图为使用strlen函数对宽字符求长度,结果为1(结果异常)。
002.png
上图为使用wcslen函数对宽字符求长度,结果为6(结果正常)。
   
    所有你喜爱的C语言中那些使用字符串参数的运行库函数都有宽字符的版本。例如wprintf是宽字符的printf。这些函数都被定义在WCHAR.H和定义正常函数的头文件中。

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-22 01:19

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表