之前使用strtoul函数时,从来没思考过它的用法,最近在编写驱动设计时,突遇这个函数,发现这函数还是有值得探讨的地方。
其函数原型如下:
unsigned long strtoul(const char *nptr,char **endptr,int base)
参数1:字符串起始地址
参数2:返回字符串有效数字的结束地址,这也是为什么要用二级指针的原因。
参数3:转换基数。当base=0,自动判断字符串的类型,并按10进制输出,例如"0xa",就会把字符串当做16进制处理,输出的为10。更多的下面详细阐述。
贴上函数原型。
#definestrtoulsimple_strtoul
#defineTOLOWER(x)((x)|0x20)
staticunsignedintsimple_guess_base(constchar*cp)
{
if(cp[0]=='0'){
if(TOLOWER(cp[1])=='x'&&isxdigit(cp[2]))
return16;
else
return8;
}else{
return10;
}
}
unsignedlongsimple_strtoul(constchar*cp,char**endp,unsignedintbase)
{
unsignedlongresult=0;
if(!base)
base=simple_guess_base(cp);
if(base==16&&cp[0]=='0'&&TOLOWER(cp[1])=='x')
cp+=2;
while(isxdigit(*cp)){
unsignedintvalue;
value=isdigit(*cp)?*cp-'0':TOLOWER(*cp)-'a'+10;
if(value>=base)
break;
result=result*base+value;
cp++;
}
if(endp)
*endp=(char*)cp;
returnresult;
}
函数分析:
1 simple_strtoul()函数里的第一个if语句,如果base=0,自动对字符串里的数字格式进行分析,并返回基数,其值可取8、16、10。第二个if语句,进一步对16进制数处理,是cp指向第三个字符。
2 while循环条件:判断是否为可处理的字符,其处理范围为‘0’-‘9’,‘a’-‘f,‘A'-'F'。
循环体内:如果*cp为数字则value=*cp-'0';如果*cp为字符value=*cp-’a‘+10。
判断value的值,如果value>=base,表明其值超过了基数,是一个不合法的数字,跳出循环。例如基数base=3, 数码符号为0,1,2,3。 此时value=4时就不是一个数码符号。
3 处理尾指针,使其指向字符串有效数字的结束地址。
4 返回result。
测试代码:
#include"stdafx.h"
#include<iostream>
#include<stdlib.h>
usingnamespacestd;
int_tmain(intargc,_TCHAR*argv[])
{
unsignedintnum1,num2,num3,num4,num5,num6;
char*stop_at=NULL;
chartemp1[16]="0xa";
chartemp2[16]="011";
chartemp3[16]="123";
chartemp4[16]="0xa";
chartemp5[16]="11";
chartemp6[16]="Z";
//ifbase==0
num1=strtol(temp1,&stop_at,0);
num2=strtol(temp2,&stop_at,0);
num3=strtol(temp3,&stop_at,0);
//ifbase>1&&base<=32
num4=strtol(temp4,&stop_at,16);
num5=strtol(temp5,&stop_at,2);
num6=strtol(temp6,&stop_at,36);
cout<<num1<<endl;
cout<<num2<<endl;
cout<<num3<<endl;
cout<<num4<<endl;
cout<<num5<<endl;
cout<<num6<<endl;
return0;
}
测试结果:
10
9
123
10
3
35
注意:
1 如果字符串以非数字开始,返回值0。
2 基数表示把字符串里的数字当做base进制处理,输出的结果把base进制转换成了10进制。
3 base=0时,会自动对字符串进行处理,例如以0x开始,其字符串看做是16进制数;以0开始,其字符串看做是8进制数。
4 如果base=n(1<n<=36),为什么可取到36,很简单,10个数字+26个字母=36。
5 如果base=1时呢? 经测试出现调试错误,也很简单,你听过1进制数吗?!。
6 尾指针指向字符串有效数字的结束地址。