首页 > 试题广场 >

实现strtol函数,其原型如为int strtol(con

[问答题]
实现strtol函数,其原型如为int strtol(const char *num_str, char **endptr, int base),num_str存放待转换的字符串,可以是负数也可以是正数;endptr指向第一个非法字符的地址,如果endptr为null则不指向第一个非法字符的地址;base用于指示进制,若base为0,则根据num_str的指示来转换。函数必须检查溢出,如果正数溢出,返回int_max;若负数溢出,返回int_min。
#include<iostream>
using namespace std;

const int int_max = 2147483647;
const int int_min = -2147483648;

bool isAlph(char num)
{
	if ((num >= 'A'&& num <= 'Z') || (num >= 'a'&& num <= 'z'))
		return true;
	else
		return false;
}

bool isDigit(char num)
{
	if ((num >= '0'&& num <= '9'))
		return true;
	else
		return false;
}

char toLower(char num)
{
	char result = num;
	if (num >= 'A' && num <= 'Z')
		result += 32;
	return result;
}
int strtoLL(const char *num_str, char **endptr, int base)
{
	long long result = 0;
	long long value;
	if (!base)
	{
		if (*num_str == '0')
		{
			num_str++;
			if (*num_str == 'x' || *num_str == 'X')
			{
				base = 16;
				num_str++;
			}
			else
				base = 8;
		}
		else
			base = 10;
	}
	while (true)
	{
		if (isAlph(*num_str) || isDigit(*num_str))
		{
			value = isAlph(*num_str) ? toLower(*num_str) - 'a' + 10 : *num_str - '0';
			if (value >= base)
				break;
			result = result*base + value;
			if (result > int_max)
				result = int_max;	
			if (result < int_min)
				result = int_min;
			num_str++;
		}
		else
			break;
	}
	if (endptr)
		*endptr = const_cast<char*> (num_str);
	return result;
}

int Mystrtol(const char *num_str, char **endptr, int base)
{
	if (*num_str == '-')
	{
		 long result = strtoLL(num_str + 1, endptr, base);
		 if (result == int_max)
			 return int_min;
		 else
			 return -result;
	} 
	return strtoLL(num_str, endptr, base);
}

int main()
{
	char *str = "0123456789ABCDEFGHItest";
	char *temp;
	cout << "******Mystrtol********" << endl;
	int result = Mystrtol(str, &temp,0);
	cout << result << endl;
	cout << temp << endl;
	cout << "******strtol**********" << endl;
	result = strtol(str, &temp,0);
	cout << result << endl;
	cout << temp << endl;
	system("pause");
	return 0;
}

编辑于 2016-08-30 19:07:40 回复(0)
#define LONG_MAX 2147483647L 
#define LONG_MIN (-2147483647L-1L)
#include<stdio.h>
long strtol ( char *  nptr, char  **  endptr, int  base   )  {
      const char *s = nptr;
     unsigned long acc;
      unsigned char c;
    unsigned long cutoff;
     int neg = 0,any, cutlim;
//判断正负号   
  do{ c = *s++;
      } while (c==' ');
      if (c == '-')
    {
          neg = 1;
         c = *s++;
    }
      else if (c == '+')
          c = *s++;
//判断进制数
      if ((base == 0 || base == 16) &&
          c == '0' && (*s == 'x' || *s == 'X'))
      {
          c = s[1];
          s += 2;
          base = 16;
      }
      if (base == 0)
          base = c == '0' ? 8 : 10;
  
//溢出处理
     cutoff = neg ? -(unsigned long) LONG_MIN : LONG_MAX;
     cutlim = cutoff % (unsigned long) base;
      cutoff /= (unsigned long) base;
      for (acc = 0, any = 0;; c = *s++)
      {
         if (c>='0'&&c<='9')
              c -= '0';
          else if ((c>='A'&&c<='Z')||(c>='a'&&c<='z'))
             c -= (c>='A'&&c<='Z') ? 'A' - 10 : 'a' - 10;
          else
              break;
          if ((int) c >= base)
              break;
          if (any < 0 || acc > cutoff || acc == cutoff && (int) c > cutlim)
              any = -1;
          else
          {
              any = 1;
              acc *= base;
             acc += c;
          }
      }
//超过范围则输出range error
     if (any < 0)
      {
        // acc = neg ? LONG_MIN : LONG_MAX;
          //errno = ERANGE;
    printf("range error.\n");
      }
      else if (neg)
          acc = -acc;
      if (endptr != 0)
         *endptr = any ?(char *) ( s - 1) : (char *) nptr;
      return acc;
 }
int main(){
 char*nptr="-0x12G 00,";char  *endptr[100];int  base=0;
 long n= strtol ( nptr,   endptr, base) ;
 printf("n=%ld\nendptr=%s\n",n,*endptr);
}
发表于 2015-08-24 20:51:56 回复(0)