现在的位置: 首页 > 综合 > 正文

strtol和十六进制转二进制

2013年02月19日 ⁄ 综合 ⁄ 共 5429字 ⁄ 字号 评论关闭

今天,在review 一些代码的时候,看到了strtol()这个函数,由于以前使用它的时候,还没有深刻的了解,这次,我决定探个究竟。

网上关于这个函数的资料大都来源于同份资料,linux库函数,讲的不够细致。于是,我花了几个小时,认真地尝试其功能,并整理了这篇文章,希望能对C语言的爱好者一些帮助。

希望大家能够将本文中发现的错误及时反馈给我,以便修正。我的信箱是wp.qin@sunmedia.com

+----------------+
|      strtol             |
+----------------+

i.e. string to long

long int strtol(const char *nptr, char **endptr, int base)
strtol()会将nptr指向的字符串,根据参数base,按权转化为long int, 然后返回这个值。
参数base的范围为2~36,和0;它决定了字符串以被转换为整数的权值。
可以被转换的合法字符依据base而定,举例来说,当base为2时,合法字符为‘0’,‘1’;base为8时,合法字符为‘0’,‘1’,……‘7’;base为10时,合

法字符为‘0’,‘1’,……‘9’;base 为16时,合法字符为‘0’,‘1’,……‘9’,‘a’,……‘f’;base为24时,合法字符为‘0’,……‘9’,‘a’,……‘n’,base

为36时,合法字符为‘0’,……‘9’,‘a’,……‘z’;等等。其中,不区分大小写,比如,‘A’和‘a’会都会被转化为10。
当字符合法时,‘0’,……‘9’依次被转换为十进制的0~9,‘a’,……‘z’一次北转换为十进制的10~35。
strtol()函数检测到第一个非法字符时,立即停止检测,其后的所有字符都会被当作非法字符处理。合法字符串会被转换为long int, 作为函数的返

回值。非法字符串,即从第一个非法字符的地址,被赋给*endptr。**endptr是个双重指针,即指针的指针。strtol()函数就是通过它改变*endptr的值,即把第一个非法字符的地址传给endptr。

多数情况下,endptr设置为NULL, 即不返回非法字符串。
下面看几个例子:
------------------------------------------------------
char buffer[20]="10379cend$3";
char *stop;
printf("%d/n",strtol(buffer, &stop, 2));
printf("%s/n", stop);
输出结果:
2
379cend$3
-------------------------------------------------------
char buffer[20]="10379cend$3";
char *stop;
printf("%d/n",strtol(buffer, &stop, 8));
printf("%s/n", stop);
输出结果:
543
9cend$3
--------------------------------------------------------
char buffer[20]="10379cend$3";
char *stop;
printf("%d/n",strtol(buffer, &stop, 10));
printf("%s/n", stop);
输出结果:
10379
cend$3
-------------------------------------------------------
char buffer[20]="10379cend$3";
char *stop;
printf("%d/n",strtol(buffer, &stop, 16));
printf("%s/n", stop);
输出结果:
17005006
nd$3
另外,如果base为0,且字符串不是以0x(或者0X)开头,则按十进制进行转化。如果base为0或者16,并且字符串以0x(或者0X)开头,那么,x(

或者X)被忽略,字符串按16进制转化。如果base不等于0和16,并且字符串以0x(或者0X)开头,那么x被视为非法字符。
例如:
-------------------------------------------------------
char buffer[20]="0x31da6c";
char *stop;
printf("%d/n",strtol(buffer, &stop, 0));
printf("%s/n", stop);
输出结果(stop为空):
3267180

-------------------------------------------------------
char buffer[20]="0x31da6c";
char *stop;
printf("%d/n",strtol(buffer, &stop, 13));
printf("%s/n", stop);
输出结果:
0
0x31da6c
-------------------------------------------------------

最后,需要说明的是,对于nptr指向的字符串,其开头和结尾处的空格被忽视,字符串中间的空格被视为非法字符。
例如:
-------------------------------------------------------
char buffer_1[20]="10379c";
char buffer_2[20]="      10379c        ";
char buffer_3[20]="      10      379c        ";
printf("%d/n",strtol(buffer_1,NULL,0));
printf("%d/n",strtol(buffer_2,NULL,0));
printf("%d/n",strtol(buffer_3,NULL,0));
输出结果为:
10379
10379
10
-----------------------------------------------------------

----------------------------------------  分割线 ---------------------------------------------------

上面是转载的内容

下面是自己的一些理解:

 

1.对于strtol的返回值问题

 

RETURN VALUE
       The  strtol() function returns the result of the conversion, unless the value would
       underflow or overflow.  If an underflow occurs, strtol() returns LONG_MIN.   If  an
       overflow occurs, strtol() returns LONG_MAX.  In both cases, errno is set to ERANGE.
       Precisely the same holds for strtoll() (with LLONG_MIN  and  LLONG_MAX  instead  of
       LONG_MIN and LONG_MAX).

 

在man手册中有这样一段返回值的介绍,这说明strtol这个函数的出错只有两种,第一是上溢,第二是下溢,两种分别对应于不同的返回值LONG_MAX和LONG_MIN。所以在用这个函数的时候一定要判断转出的数值不能溢出。

 

 

2.关于strtol中endptr的问题

 

错误的理解:

上面是一段十六进制字符串转二进制字符串的代码,在函数结尾,我本来想用endptr来判断strtol的转换是否正确,当时的想法是:如果一个纯以'0'或'1'字符构成的字符串,那么正确转换后endptr应该是NULL。

 

试验结果:

 

执行结果:

 

 

经过上述代码的一个测试,可以发现:

1. 当字符串中的字符完全符合转换所规定进制的格式要求时,*ptr = '/0',无论是否溢出(情况1和2)

2. 当字符串中出现非法字符,那么*ptr = 第一个非法字符。

3. LONG_MAX和LONG_MIN 常数在<limit.h>头文件中。

 

抱歉!评论已关闭.