注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

信息 灵感 创新

I? =Information,Inspiration,Innovation

 
 
 

日志

 
 
关于我

we are 5. Mathematics, Computation, Programming, Engineering, and Making fun of life.

网易考拉推荐

字符串长度与大小相关函数  

2014-07-02 17:25:18|  分类: Windows编程 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

在Windows编程的时候,能碰到许多字符串相关的函数,这些函数中经常包含了一个字符串长度的参数,由于字符分为ANSI字符和Unicode(宽)字符,因此,弄清楚在什么情况下使用何种计算字符串长度的函数,从而为函数传递正确的参数显得很重要,这里总结一下常见的一些字符串长度函数。

1. ANSI字符串指针和字符数组

C语言中的字符串通常有两种形式,一种是常量字符指针,另外一种是字符数组,这两种字符串都是以’\0’作为结尾(如果是Unicode则是连续两个’\0’)。虽然这两种形式的字符串在很多函数中都能作为传入的参数,但是还是有一些区别的。最常见的区别是,ANSI版本下的strlen函数,以及sizeof操作符。

#include <stdlib.h>
int main()
{
    char* pChar="Hello, world!";
    char arrChar1[]="Hello, world!";
    char arrChar2[24]="Hello, world!";
    printf("strlen:%d\t%d\t%d\n",strlen(pChar),strlen(arrChar1),strlen(arrChar2));
    printf("sizeof:%d\t%d\t%d\n",sizeof(pChar),sizeof(arrChar1),sizeof(arrChar2));
    return 0;
}
程序运行的结果如下:
image
简单的对比分析:
a.对于字符指针和字符数组,strlen都是根据所提供参数的首地址计算,直到碰到下一个’\0’,这之间的字符个数(不包括’\0’)就是字符串的长度,而且strlen无视字符数组的大小,上面的例子中arrChar2为24,实际字符串长度为13,如果数组由于误操作,导致一个长度为n的数组arr,其arr[n-1]不为’\0’,strlen还会继续计数,感兴趣的可以自己测试一下。(为了克服这个问题,还带来了strnlen)函数。
b.不同于strlen通过检索’\0’来获取字符串长度,sizeof对字符指针和字符数组表现出完全不同的行为。对于一个字符指针,返回的结果是指针的字节数目(x86环境下,指针的大小都是4字节),而对于字符数组,则是字符数组的容量,即初始声明时字符指针的大小,而且,sizeof还会将’\0’计算在内。
在把这个问题讲清楚之后,我们再把事情变得复杂一些。
2. ANSI VS Unicode
先强调一个非常重要也是最基本的概念:ANSI字符占一个字节,Unicode字符占两个字节(下面在谈到Unicode字符时,用宽字符表示)。
如果将上面的字符变为宽字符,即将char类型都变为wchar_t类型,则程序及输出结果如下:
#include <stdlib.h>
int main()
{
    wchar_t* pChar=L"Hello, world!";
    wchar_t arrChar1[]=L"Hello, world!";
    wchar_t arrChar2[24]=L"Hello, world!";
    printf("strlen:%d\t%d\t%d\n",wcslen(pChar),wcslen(arrChar1),wcslen(arrChar2));
    printf("sizeof:%d\t%d\t%d\n",sizeof(pChar),sizeof(arrChar1),sizeof(arrChar2));
    return 0;
}

image

注意,宽字符的长度函数要使用wcslen,而不是strlen。

对比可以发现wcslen针对宽字符指针和宽字符数组的效果与strlen类似,都是字符的个数(依旧不包括’\0’),而sizeof也和前面ANSI字符版本的结果类似,对于宽字符指针,还是四个字节,但是对于数组,值都变为前者的两倍,因为1个宽字符占两个字节。

前面的这些知识,对于掌握C语言的基础知识来说,已经足够了,但是在Windows编程时,事情还会变得更加复杂。

区分字符和宽字符的区别在Windows编程中具有很重要的意义,由于许多函数都有A版本(ANSI)和W版本(Unicode,Wide Char)两种,还带来了新的函数。

3. lstrlen系列

就像windows函数MessageBox一样,本质上并不存在这一函数,该函数在Winbase.h下的宏定义为:

#ifdef UNICODE
#define lstrlen  lstrlenW
#else
#define lstrlen  lstrlenA
#endif 

可见,实际上只有lstrlenW和lstrlenA两个函数。而lstrlenW等效为wcslen,lstrlenA等效为strlen。

4. sizeof和_countof

sizeof用来计算字符(或者宽字符)数组中的字节数(包括’\0’),而_countof是Windows下面的一个宏,用来计算数组中的元素个数。

char ac[]="Hello, world!";
wchar_t wc[]=L"Hello, world!";
printf("sizeof:%d\t%d\n",sizeof(ac),sizeof(wc));
printf("_countof:%d\t%d\n",_countof(ac),_countof(wc));
这段代码运行的结果是:
image
可以看到,_countof不管对于ANSI字符还是Unicode字符,都是计算包括终止符在内的字符个数的。因此在ANSI环境下,sizeof和_countof效果相同,但是在Unicode下,对同一个字符数组,_countof返回的结果是sizeof的两倍。另外一个区别是,sizeof可以接受指针(虽然这个时候返回值总是4),但是_countof则只能接受一个数组。

5. StringCbLength和StringCchLength函数

这两个函数同样是有A和W两个版本,判断字符串是否在数量上超出指定的长度,通常用于代替strlen和wcslen。其中Cb表示count by byte,而Cch表示count by char,即一个是使用字节,而另一个使用字符。

  评论这张
 
阅读(644)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2016