淡泊明志 宁静致远
分类: C/C++
2007-01-04 08:36:19
【C语言库函数源代码】
【本程序在Dev C++ 4.9.9.2 下编译通过】
/*
这个函数会将参数nptr字符串根据参数base来转换成长整型数。
参数base范围从2至36,或0。参数base代表采用的进制方式,
如base值为10则采用10进制,若base值为16则采用16进制等。
当base值为0时则是采用10进制做转换,但遇到如’0x’前置
字符则会使用16进制做转换、遇到’0’前置字符而不是’0x’
的时候会使用8进制做转换。一开始strtol()会扫描参数nptr
字符串,跳过前面的空格字符,直到遇上数字或正负符号才
开始做转换,再遇到非数字或字符串结束时('\0')结束转换,
并将结果返回。若参数endptr不为NULL,则会将遇到不合条件
而终止的nptr中的字符指针由endptr返回。
*/
#include
#define
LONG_MAX 2147483647L /*0x7FFFFFFF*/
#define
LONG_MIN (-2147483647L-1L) /*-0x80000000*/
int my_strtol(const char *nptr, char
**endptr, int base)
{
const char *p = nptr;
unsigned long ret;
int ch;
unsigned long Overflow;
int sign = 0,
flag, LimitRemainder;
/*
跳过前面多余的空格,并判断正负符号。
如果base是0,允许以0x开头的十六进制数,
以0开头的8进制数。
如果base是16,则同时也允许以0x开头。
*/
do
{
ch = *p++;
} while
(isspace(ch));
if (ch ==
'-')
{
sign = 1;
ch = *p++;
}
else if (ch == '+')
ch = *p++;
if ((base ==
0 || base == 16) &&
ch == '0' && (*p == 'x' || *p ==
'X'))
{
ch = p[1];
p += 2;
base = 16;
}
if (base ==
0)
base = ch == '0' ? 8 : 10;
Overflow = sign ? -(unsigned
long)LONG_MIN : LONG_MAX;
LimitRemainder = Overflow % (unsigned long)base;
Overflow /= (unsigned
long)base;
for (ret = 0,
flag = 0;; ch = *p++)
{
/*把当前字符转换为相应运算中需要的值。*/
if
(isdigit(ch))
ch -= '0';
else if (isalpha(ch))
ch -= isupper(ch) ? 'A' - 10 : 'a' - 10;
else
break;
if (ch
>= base)
break;
/*如果产生溢出,则置标志位,以后不再做计算。*/
if (flag
< 0 || ret > Overflow || (ret == Overflow && ch >
LimitRemainder))
flag = -1;
else
{
flag = 1;
ret *= base;
ret += ch;
}
}
/*
如果溢出,则返回相应的Overflow的峰值。
没有溢出,如是符号位为负,则转换为负数。
*/
if (flag <
0)
ret = sign ? LONG_MIN : LONG_MAX;
else if (sign)
ret = -ret;
/*
如字符串不为空,则*endptr等于指向nptr结束
符的指针值;否则*endptr等于nptr的首地址。
*/
if (endptr !=
0)
*endptr = (char
*)(flag ?(p - 1) : nptr);
return ret;
}
int main()
{
char * str =
"2147483647";
printf("%d\n",my_strtol(str, NULL,
0));
str = "-2147483648";
printf("%d\n",my_strtol(str, NULL,
0));
str = "0x7FFFFFFF";
printf("%d\n",my_strtol(str, NULL,
0));
str = "-0x80000000";
printf("%d\n",my_strtol(str, NULL,
0));
str = "0x7FFFFFFF";
printf("%d\n",my_strtol(str, NULL,
16));
str = "-0x80000000";
printf("%d\n",my_strtol(str, NULL,
16));
str = "017777777777";
printf("%d\n",my_strtol(str, NULL,
0));
str = "-020000000000";
printf("%d\n",my_strtol(str, NULL,
0));
system("pause");
return 0;
}
chinaunix网友2009-10-30 22:39:26
LZ在哪可以找到c函数库的源码了?可以告我一下吗?我找了好几天了,都没找到,想看看源码了。谢谢LZ,我的邮箱是:baiyongjie8179218@163.com