strlen掉坑实例
编码目标:
根据字符串起点打印不一样偏移(Offset)到结尾的字符串,若是Offset为负数就向前移动并打印到字符串末尾。web
掉坑示例:svg
1#include <stdio.h> 2#include <string.h> 3/*************************************** 4 * Fuction:sGetStr 5 * Decri :打印相应位置到末尾的字符串 7 ***************************************/ 8int sGetStr(const char * str,int offset) 9{ 10 if(offset > strlen(str)) 11 { 12 printf("offset Over Error!!\n"); 13 } 14 else 15 { 16 printf("%s\n",str + offset); 17 } 18} 19/*************************************** 20 * Fuction:main 21 * Decri :不一样起点位置的字符串打印 23 ***************************************/ 24int main(int argc, char *argv[]) { 25 26 char * pSrstr = "0123456789"; 27 28 sGetStr(pSrstr + 5,0); 29 sGetStr(pSrstr + 5,-2); 30 31 printf("欢迎关注公众号:最后一个bug\n"); 32 return 0; 33}
输出结果:
第一次打印可以成功,而第二次采用负数Offset打印直接比较失败,很明显Offset为负数却大于了strlen返回值,基本上咱们确定strlen确定是正数,那为啥会失败呢?咱们还得查查strlen的函数原型。函数
size_t分析
因而找来了一个strlen的函数声明:
经过上面的声明咱们了解到size_t是一个与系统有关的定义类型,系统为了加强可移植性等等会进行不一样的处理,到这里应该会有点想法,难道这个size_t是一个无符号类型?编码
由于以前咱们也说过整形数据的提高问题<【重磅】“整形数”还真没那么简单(C语言版)>,若是unsigned int与int进行运算会统一提高为无符号来处理,这样也会致使出现上面的结果。spa
得找找size_t的具体实现,经过查找C标准库了解到,size_t是一个无符号的整形类型,以下图所示:
总感受说明虚了一点,仍是上代码比较实在点,因而找来了一个具体实现:
上图能够看到size_t根据系统位数不一样,分别由unsigned int和unsigned long这样的无符号类型来实现,因此与咱们的猜想仍是相符合的。code
若是还想进一步深究,请看汇编吧!!xml
处理办法
处理办法其实挺多,能够把strlen函数返回值强制类型转化为一个有符号类型,而后再进行有符号类型比较;若是有符号数为负数也能够单独判断符号后处理。blog
下面咱们就简单的强制类型转化一下看一下结果,以前的代码作以下修改:token
1/*************************************** 2 * Fuction:sGetStr 3 * Decri :打印相应位置到末尾的字符串 5 ***************************************/ 6int sGetStr(const char * str,int offset) 7{ 8 if(offset > (int)strlen(str)) //强制转化为有符号 9 { 10 printf("offset Over Error!!\n"); 11 } 12 else 13 { 14 printf("%s\n",str+offset); 15 } 16}
输出结果:
上图的输出咱们得到了正确的结果。图片
对于平时喜欢使用size_t类型或者是一些与size_t有关的标准函数可也要注意了,否则一不当心又掉到坑里去了