Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1411888
  • 博文数量: 143
  • 博客积分: 10005
  • 博客等级: 上将
  • 技术积分: 1535
  • 用 户 组: 普通用户
  • 注册时间: 2006-10-23 17:25
个人简介

淡泊明志 宁静致远

文章分类

全部博文(143)

文章存档

2011年(2)

2009年(1)

2007年(22)

2006年(118)

我的朋友

分类: 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;

}

阅读(12726) | 评论(2) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2009-10-30 22:39:26

LZ在哪可以找到c函数库的源码了?可以告我一下吗?我找了好几天了,都没找到,想看看源码了。谢谢LZ,我的邮箱是:baiyongjie8179218@163.com