strtoul函数的使用

来源:互联网 发布:数据库开启事务 编辑:程序博客网 时间:2024/05/29 18:16

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

[cpp] view plaincopy
  1. #define strtoul                     simple_strtoul  
  2. #define TOLOWER(x) ((x) | 0x20)  
  3.   
  4. static unsigned int simple_guess_base(const char *cp)  
  5. {  
  6.     if (cp[0] == '0') {  
  7.         if (TOLOWER(cp[1]) == 'x' && isxdigit(cp[2]))  
  8.             return 16;  
  9.         else  
  10.             return 8;  
  11.     } else {  
  12.         return 10;  
  13.     }  
  14. }  
  15.   
  16. unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base)  
  17. {  
  18.     unsigned long result = 0;  
  19.   
  20.     if (!base)  
  21.         base = simple_guess_base(cp);  
  22.   
  23.     if (base == 16 && cp[0] == '0' && TOLOWER(cp[1]) == 'x')  
  24.         cp += 2;  
  25.   
  26.     while (isxdigit(*cp)) {  
  27.         unsigned int value;  
  28.   
  29.         value = isdigit(*cp) ? *cp - '0' : TOLOWER(*cp) - 'a' + 10;  
  30.         if (value >= base)  
  31.             break;  
  32.         result = result * base + value;  
  33.         cp++;  
  34.     }  
  35.   
  36.     if (endp)  
  37.         *endp = (char *)cp;  
  38.     return result;  
  39. }  

函数分析:
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。

测试代码:

[cpp] view plaincopy
  1. #include "stdafx.h"  
  2. #include   <iostream>   
  3. #include <stdlib.h>  
  4. using namespace std;  
  5. int _tmain(int argc, _TCHAR* argv[])  
  6. {  
  7.     unsigned   int   num1,num2,num3 ,num4,num5,num6   ;   
  8.     char   *stop_at  =NULL ;   
  9.     char   temp1[16]   =   "0xa"   ;   
  10.     char   temp2[16]   =   "011"   ;   
  11.     char   temp3[16]   =   "123"   ;   
  12.     char   temp4[16]   =   "0xa"   ;   
  13.     char   temp5[16]   =   "11"   ;   
  14.     char   temp6[16]   =   "Z"   ;   
  15.     //if base==0  
  16.     num1=strtol(temp1,&stop_at,0);   
  17.     num2=strtol(temp2,&stop_at,0);   
  18.     num3=strtol(temp3,&stop_at,0);   
  19.     //if base>1 && base <=32  
  20.     num4=strtol(temp4,&stop_at,16);   
  21.     num5=strtol(temp5,&stop_at,2);   
  22.     num6=strtol(temp6,&stop_at,36);   
  23.   
  24.     cout<<num1<<endl;  
  25.         cout<<num2<<endl;  
  26.     cout<<num3<<endl;  
  27.     cout<<num4<<endl;  
  28.     cout<<num5<<endl;  
  29.     cout<<num6<<endl;  
  30.     return 0;  
  31. }  
测试结果:
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  尾指针指向字符串有效数字的结束地址。
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 天猫精灵方糖不按顺序播放怎么办 在天猫购物已付款不发货怎么办 淘宝退货商家收到货不退款怎么办 被有实名认证的闲鱼卖家骗了怎么办 我收到了方正的提示函怎么办 淘宝刷q币单被骗了怎么办 中通快递已签收但是东西丢了怎么办 手机不版本低不支持微信下载怎么办 淘宝虚拟商品不支持7天退货怎么办 卖虚拟物品遇到恶意退款买家怎么办 淘宝极速退款后卖家拒绝退款怎么办 我的天猫积分不让换券了怎么办 微信手机话费充错了怎么办 自己进货在淘宝卖被投诉假货怎么办 京东买的电器售后后服务差怎么办 京东到家申请退款卖家不处理怎么办 天猫买了假货商品下架了怎么办 淘宝本地生活服务不能入驻了怎么办 淘宝店铺名在电脑上搜索不到怎么办 已经将退货寄回店家硬说没有怎么办 微信申诉账号短信验证失败怎么办 京东账号换手机号收不到短信怎么办 我的手机收不到短信通知怎么办? 淘宝卖家发货物流单号写错了怎么办 商铺买东西不给调换大小怎么办 圆通快递物流信息一直没更新怎么办 中通快递三天没更新物流信息怎么办 快递已经到了物流信息不更新怎么办 天天快递查询不更新物流信息怎么办 买车下个月分期全部付清怎么办手续 天猫客服介入以后商家不退款怎么办 淘宝上买代购奢侈品买到假货怎么办 淘宝退货卖家收到货拒绝退款怎么办 没收到货但申请了退货退款怎么办 小米商城预约中德手机没货怎么办 电脑用百度网盘下载速度超慢怎么办 ios网盘下载速度太慢怎么办 小米手机4x卡机了怎么办 小米手机4x屏幕点不动了怎么办 苹果手机连接u盘没反应怎么办 苹果官网储蓄卡分期额度不够怎么办