atoi函数的实现(考虑不同进制、溢出)

时间:2023-03-09 17:12:10
atoi函数的实现(考虑不同进制、溢出)

2013-07-08 16:21:15

atio就是将ASCII码表示的字符为int型数据,看似简单的问题,实际上需要考虑的很多。对于简单的问题,考虑是否全面就显得特别重要。

小结:

对于该函数的实现要考虑一下几个方面:

  1. 输入字符串为NULL;
  2. 输入开始是否包含符号'+'、'-'
  3. 输入的字符是否合法(对十进制'0' ~'9'为合法的输入);
  4. 计算出的 数值必须为unsigned Int,才能判断溢出;
  5. 数据溢出的处理(上溢出时,返回最大正数;下溢出时,返回最大负数);
  6. 输入的字符包含前导的空格;
  7. 进制的考虑,考虑16进制以及8进制,通过开头的0或0x判断进制;
  8. 对于不同的进制判断的范围不同
    对16进制0123456789ABCDEF或0123456789abcdef
    对8进制01234567
    对10进制0123456789

其中,前4点是最基本的功能,后面两点则算是功能的扩展,根据不同的要求还可以进行扩展,比如加上各种状态标志,表明是否溢出、输入是否合法,具体在函数_atoi_3中有体现。

另外,在编写代码时,还有几点需要注意:

判断是否溢出时,用到的最大数必须为unsigned long int,这样才能表示绝对值最大的负数。

在考虑进制时,比较繁琐,按照下面步骤来做:

根据首个非空字符判断符号:

if (0 == sign)  //判断数值的符号
  {
   if ('+' == *str)
   {
    sign = 1;
    ++str;
   }
   else if('-' == *str)
   {
    sign = -1;
    ++str;
   }
   else if ( isdigit(*str) )
   {
    sign = 1;
   }
  }

接下来,判断进制:

if (0 == base) //判断数值的进制
    {
     if ( '0' == *str && ( 'x' == *(str + 1) || 'X' == *(str + 1) ) )
     {
      base = 16;
      str = str + 2;
     }
     else if ( '0' == *str && !( 'x' == *(str + 1) || 'X' == *(str + 1) ) )
     {
      base = 8;
      str = str + 1;
     }
     else
     {
      base = 10;   //不更新str
     }
    }

 计算出数据后,判断溢出:

if (IsOverflow (IntNumber,sign) == 1)
     {
      return MaxPositive;
     }

if (IsOverflow (IntNumber,sign) == -1)
     {
      return -( ( MaxPositive + 1) );
     }

参考:http://blog.csdn.net/tianshuai11/article/details/7798698


代码(测试暂无发现问题,如发现问题,欢迎指正!):

 #include <iostream>
#include <cmath>
using namespace std; #define SIZE 100 //没有区别输入0与\0
//只能对十进制数进行转换
//没有处理溢出
int _atoi_1(char *str)
{
if (NULL == str) //输入合法性检查
{
cout<<"NULL input"<<endl;
exit();
} int sign = ;
int IntNumber = ; while ( *str )
{
if ( == sign)
{
if ('-' == *str)
{
sign = -;
++str;
}
else if ('+' == *str)
{
sign = ;
++str;
}
else if (*str >= '' && *str <= '')
{
sign = ; //不更新str
}
else
{
cout<<"invalid input!"<<endl;
exit();
}
}
else if (*str >= '' && *str <= '')
{
IntNumber = IntNumber* + *str - '';
++str;
}
else
{
cout<<"invalid input!"<<endl;
exit();
}
} return (sign * IntNumber);
} //加上溢出处理
//并可对10进制、16进制以及8进制转换
//状态标志
bool IsNotNULL = true;
bool IsDigit = true;
bool IsNotOverflow = true; int IsOverflow (unsigned long int IntNumber,int sign)
{
unsigned long int MaxPositive = (long int) pow( (float),(int)( *sizeof(long int) - ) ) - ; if ( (sign == ) && !(IntNumber >= && IntNumber <= MaxPositive ) ) //判断是否溢出
{
IsNotOverflow = true;
return ;
} if ( (sign == -) && !(IntNumber > && IntNumber <= (MaxPositive + ) ) ) //判断是否溢出
{
IsNotOverflow = true;
return -;
} return ;
} long int _atoi_2(char *str)
{
if (NULL == str)
{
IsNotNULL = false;
return ;
} int sign = ;
unsigned long int MaxPositive = (long int) pow( (float),(int)( *sizeof(long int) - ) ) - ;
unsigned long int IntNumber = ; //要表示最小负数,须用unsigned long int,若用long int,其范围为-2^31到2^31 -1,不能表示2^31
unsigned int base = ; while ( *str )
{
while ( ' ' == *str || '\t' == *str) //忽略前导的空格或TAB
++str; if ( == sign) //判断数值的符号
{
if ('+' == *str)
{
sign = ;
++str;
}
else if('-' == *str)
{
sign = -;
++str;
}
else if ( isdigit(*str) )
{
sign = ;
}
}
else
{
if ( isdigit(*str) )
{
if ( == base) //判断数值的进制
{
if ( '' == *str && ( 'x' == *(str + ) || 'X' == *(str + ) ) )
{
base = ;
str = str + ;
}
else if ( '' == *str && !( 'x' == *(str + ) || 'X' == *(str + ) ) )
{
base = ;
str = str + ;
}
else
{
base = ; //不更新str
}
}
else
{
IntNumber = IntNumber * base + *str - ''; if (IsOverflow (IntNumber,sign) == )
{
return MaxPositive;
} if (IsOverflow (IntNumber,sign) == -)
{
return -( ( MaxPositive + ) );
} ++str;
}
}
else
{
IsDigit = false;
return ;
}
}
} return (sign * IntNumber); //如果为空串,也即第一个字符即为\0,返回值为0
}
//对不同的进制,判断的范围不同
//对16进制0123456789ABCDEF
//对8进制01234567
//对10进制0123456789
long int _atoi_3(char *str)
{
if (NULL == str) //输入合法性检查
{
IsNotNULL = false;
return ;
} int sign = ;
unsigned long int IntNumber = ; //要表示最小负数,须用unsigned long int,若用long int,其范围为-2^31到2^31 -1,不能表示2^31
unsigned long int MaxPositive = (long int) pow( (float),(int)( *sizeof(long int) - ) ) - ;
unsigned int base = ; while ( *str )
{
while ( ' ' == *str || '\t' == *str) //忽略前导的空格或TAB
++str; if ( == sign) //判断数值的符号
{
if ('+' == *str)
{
sign = ;
++str;
}
else if('-' == *str)
{
sign = -;
++str;
}
else if ( isdigit(*str) )
{
sign = ;
}
else
{
IsDigit = false;
return ;
}
}
else
{
if ( == base) //判断数值的进制
{
if ( '' == *str && ( 'x' == *(str + ) || 'X' == *(str + ) ) )
{
base = ;
str = str + ;
}
else if ( '' == *str && !( 'x' == *(str + ) || 'X' == *(str + ) ) )
{
base = ;
str = str + ;
}
else
{
base = ; //不更新str
}
}
else
{
if ( == base)
{
if ( isdigit(*str) )
{
IntNumber = IntNumber * base + *str - '';
if (IsOverflow (IntNumber,sign) == )
{
return MaxPositive;
} if (IsOverflow (IntNumber,sign) == -)
{
return -( ( MaxPositive + ) );
}
++str;
}
else
{
IsDigit = false;
return ;
}
}
else if ( == base)
{
if ( isdigit(*str) || (*str >= 'a'&& *str <= 'f') || (*str >= 'A'&& *str <= 'F'))
{
if ( isdigit(*str))
{
IntNumber = IntNumber * base + *str - '';
}
else if (*str >= 'a'&& *str <= 'f')
{
IntNumber = IntNumber * base + *str - 'a' + ;
}
else if (*str >= 'A'&& *str <= 'F')
{
IntNumber = IntNumber * base + *str - 'A' + ;
} if (IsOverflow (IntNumber,sign) == )
{
return MaxPositive;
} if (IsOverflow (IntNumber,sign) == -)
{
return -( ( MaxPositive + ) );
}
++str;
}
else
{
IsDigit = false;
return ;
}
}
else
{
if ( *str>= '' && *str <= '')
{
IntNumber = IntNumber * base + *str - '';
if (IsOverflow (IntNumber,sign) == )
{
return MaxPositive;
} if (IsOverflow (IntNumber,sign) == -)
{
return -( ( MaxPositive + ) );
}
++str;
}
else
{
IsDigit = false;
return ;
}
}
}
}
} return (sign * IntNumber); //如果为空串,也即第一个字符即为\0,返回值为0
} //测试程序
int main()
{
char str[SIZE]; cout<<"size of type int is : "<<sizeof(int)<<endl; //
cout<<"size of type long int is : "<<sizeof(long int)<<endl; //
cout<<"size of type float is : "<<sizeof(float)<<endl; //
cout<<"size of type long double is : "<<sizeof(long double)<<endl; //
/*char str[SIZE] = "100278";
char str[SIZE] = "+1267
char str[SIZE] = "-12";
char str[SIZE] = "+";
char str[SIZE] = "-";
char str[SIZE] = "";
char str[SIZE] = "z98";
char str[SIZE] = "-9s8";*/ //test _atoi_1...
cout<<"test _atoi_1..."<<endl;
cout<<"please enter the string :"<<endl;
while(cin>>str)
{
cout<<"the string is :"<<str<<endl;
cout<<"the int number is : "<<_atoi_1(str)<<endl;
cout<<"please enter the string :"<<endl;
} cin.clear();
cin.sync();
cout<<endl; //test _atoi_2...
cout<<"test _atoi_2..."<<endl;
cout<<"please enter the string :"<<endl;
while(cin>>str)
{
cout<<"the string is :"<<str<<endl;
cout<<"the int number is : "<<_atoi_2(str)<<endl;
cout<<"please enter the string :"<<endl;
} cin.clear();
cin.sync();
cout<<endl; //test _atoi_3...
cout<<"test _atoi_3..."<<endl;
cout<<"please enter the string :"<<endl;
while(cin>>str)
{
cout<<"the string is :"<<str<<endl;
cout<<"the int number is : "<<_atoi_3(str)<<endl;
cout<<"please enter the string :"<<endl;
} return ;
}

对代码的测试也要注意开头中提到的几点,运行结果:

size of type int is :
size of type long int is :
size of type float is :
size of type long double is :
test _atoi_1...
please enter the string : the string is :
the int number is :
please enter the string :
+
the string is :+
the int number is :
please enter the string :
-
the string is :-
the int number is : -
please enter the string : the string is :
the int number is :
please enter the string : the string is :
the int number is :
please enter the string : the string is :
the int number is : -
please enter the string :
-
the string is :-
the int number is :
please enter the string :
^Z test _atoi_2...
please enter the string : the string is :
the int number is :
please enter the string :
-
the string is :-
the int number is : -
please enter the string :
-
the string is :-
the int number is : -
please enter the string :
0x1a
the string is :0x1a
the int number is :
please enter the string : the string is :
the int number is :
please enter the string :
0x89
the string is :0x89
the int number is :
please enter the string :
0xaa
the string is :0xaa
the int number is :
please enter the string :
^Z test _atoi_3...
please enter the string : the string is :
the int number is :
please enter the string :
-
the string is :-
the int number is : -
please enter the string :
0x1a
the string is :0x1a
the int number is :
please enter the string :
-0xaa
the string is :-0xaa
the int number is : -
please enter the string : the string is :
the int number is :
please enter the string : the string is :
the int number is :
please enter the string :
^Z
请按任意键继续. . .