strtoul函数的使用,揭开其神秘面纱

之前使用strtoul函数时,从来没思考过它的用法,最近在编写驱动设计时,突遇这个函数,发现这函数还是有值得探讨的地方。
其函数原型如下:
unsigned long strtoul(const char *nptr,char **endptr,int base )
参数1:字符串起始地址
参数2:返回字符串有效数字的结束地址,这也是为什么要用二级指针的原因。
参数3:转换基数。当base=0,自动判断字符串的类型,并按10进制输出,例如"0xa",就会把字符串当做16进制处理,输出的为10。更多的下面详细阐述。
贴上函数原型

#define strtoul                     simple_strtoul
#define TOLOWER(x) ((x) | 0x20)

static unsigned int simple_guess_base(const char *cp)
{
	if (cp[0] == '0') {
		if (TOLOWER(cp[1]) == 'x' && isxdigit(cp[2]))
			return 16;
		else
			return 8;
	} else {
		return 10;
	}
}

unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base)
{
	unsigned long result = 0;

	if (!base)
		base = simple_guess_base(cp);

	if (base == 16 && cp[0] == '0' && TOLOWER(cp[1]) == 'x')
		cp += 2;

	while (isxdigit(*cp)) {
		unsigned int value;

		value = isdigit(*cp) ? *cp - '0' : TOLOWER(*cp) - 'a' + 10;
		if (value >= base)
			break;
		result = result * base + value;
		cp++;
	}

	if (endp)
		*endp = (char *)cp;
	return result;
}

函数分析:
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>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
	unsigned   int   num1,num2,num3 ,num4,num5,num6   ; 
	char   *stop_at  =NULL ; 
	char   temp1[16]   =   "0xa"   ; 
	char   temp2[16]   =   "011"   ; 
	char   temp3[16]   =   "123"   ; 
	char   temp4[16]   =   "0xa"   ; 
	char   temp5[16]   =   "11"   ; 
	char   temp6[16]   =   "Z"   ; 
	//if base==0
	num1=strtol(temp1,&stop_at,0); 
	num2=strtol(temp2,&stop_at,0); 
	num3=strtol(temp3,&stop_at,0); 
	//if base>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;
	return 0;
}
测试结果:
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  尾指针指向字符串有效数字的结束地址。




                
  • 9
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
strtoul函数是C标准库中的一个函数,其功能是将字符串转换为无符号长整型数(unsigned long)。 strtoul函数的原型如下: unsigned long strtoul(const char *str, char **endptr, int base); 其中,str是要进行转换的字符串;endptr是指向第一个无法被转换的字符的指针;base表示转换时所使用的进制数。 strtoul函数具体的转换过程如下: 1. 从字符串的开头开始遍历,直到遇到第一个非空格字符或者非数字字符。 2. 如果第一个非空格字符是加号或者减号,则分别判断该符号的正负,并从下一个字符开始继续遍历。 3. 判断第一个非空格字符之后的字符是否合法,如果不是数字字符,则停止转换,将endptr指针指向这个非法字符。 4. 根据所给的进制数base,将字符逐个转换为数字。 5. 如果转换过程中遇到非数字字符或者超过了unsigned long类型的范围,则停止转换,将endptr指针指向转换停止的位置。 6. 如果转换成功,返回转换后的无符号长整型数。 以下是一个使用strtoul函数的例子: ``` #include <stdio.h> #include <stdlib.h> int main() { char str[] = "12345"; char *endptr; unsigned long num = strtoul(str, &endptr, 10); printf("Number: %lu\n", num); printf("Endptr: %s\n", endptr); return 0; } ``` 输出结果为: ``` Number: 12345 Endptr: ``` 其中,Number表示转换后的无符号长整型数,Endptr指向的是字符串的末尾。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值