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
请按任意键继续. . .

atoi函数的实现(考虑不同进制、溢出)的更多相关文章

  1. itoa函数的实现(不同进制)

    2013-07-08 17:12:30 itoa函数相对于atoi函数,比较简单,还是要注意考虑的全面. 小结: 一下几点需要考虑: 对负数,要加上负号: 考虑不同进制,根据要求进行处理:对不同的进制 ...

  2. strtol函数 将字符串转换为相应进制的整数

    转自http://hi.baidu.com/qwpsmile/blog/item/9bc44efa4f41018a9f514637.html +----------------+|      strt ...

  3. Datediff函数 助你实现不同进制时间之间的运算

    在VB开发环境中实现时间之间的加减运算有很多种方法,前不久自己无意中发现了Datediff函数,它能够比较简单.全面地实现我们比较常用的时间之间的运算,今由自己的研究,搞清了它的一些用法,拿来和大家分 ...

  4. 嵌入式开发之函数解析---ip地址2进制转字符inet_ntoa 调用中只生效一次

    inet_addr()   简述:将一个点间隔地址转换成一个in_addr. #include <winsock.h> unsigned long PASCAL FAR inet_addr ...

  5. C++中的各种进制转换函数汇总及学习

    一.指定格式输出 1.C中指定格式输出 printf(); //按八进制格式输出,保留5位高位补零 printf(); //按十进制格式输出,保留3位高位补零 printf(); //按十六进制格式输 ...

  6. Python中进制转换函数的使用

    Python中进制转换函数的使用 关于Python中几个进制转换的函数使用方法,做一个简单的使用方法的介绍,我们常用的进制转换函数常用的就是int()(其他进制转换到十进制).bin()(十进制转换到 ...

  7. 【C/C++】任意进制转换

    进制转换:R进制->10进制:10进制->R进制. #include<bits/stdc++.h> using namespace std; /*函数:r进制转换成10进制*/ ...

  8. 将16进制的颜色转为rgb颜色

    在前端面试过程中,常常会遇到这样一种类型的题目: 使用js将16进制的颜色值转为rgb颜色! 反而在项目中,不怎么遇到这种问题,也很少有这种需求的项目. 但毕竟面试中常常遇到,我自己在之前的面试的时候 ...

  9. 轻松实现C/C++各种常见进制相互转换

    其它进制转为十进制 在实现这个需求之前,先简单介绍一个c标准库中的一个函数: long strtol( const char *str, char **str_end, int base); 参数详细 ...

  10. leetcood学习笔记-67-二进制求和

    题目描述: 第一次提交: class Solution: def addBinary(self, a: str, b: str) -> str: list_a,list_b=[],[] for ...

随机推荐

  1. L1范式和L2范式的区别

    L1 and L2 regularization add a cost to high valued weights to prevent overfitting. L1 regularization ...

  2. spring-cloud-bus

    安装rabbitmq 依赖erlang: http://erlang.org/download/otp_win64_18.2.exe

  3. 解析php file_exists无效的解决办法

    php中file_exists无效的解决办法. 方法1 :据官方手册上描述若php教程的safe mode相关的设置过于苛刻,就会出现这样的情形:尽管文件真实存在也被误报,认为文件不存在. 由于服务器 ...

  4. Spark Streaming揭秘 Day29 深入理解Spark2.x中的Structured Streaming

    Spark Streaming揭秘 Day29 深入理解Spark2.x中的Structured Streaming 在Spark2.x中,Spark Streaming获得了比较全面的升级,称为St ...

  5. 1027 Colors in Mars (20)

    #include <stdio.h> #include <map> using namespace std; int main() { int R,G,B,i; map< ...

  6. ORA-15025: could not open disk 处理

    刚才下班回家的路上,接到客户的电话:"回家了吗?我们这边的一套RAC库有个节点有问题哦,一直刷异常,一下子就把磁盘弄满了,我现在停掉了那个节点了.从日志上看好像跟权限有关,现在还有个实例跑着 ...

  7. 关于WinForm引用WPF窗体

    项目中有个界面展示用WPF实现起来比较简单,并且能提供更酷炫的效果,但是在WinForm中使用WPF窗体出现了问题,在网上找了一下有些人说Winform不能引用WPF的窗体,我就很纳闷,Win32都能 ...

  8. [原创] zabbix学习之旅一:源码安装

    zabbix是一个基于WEB界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案.zabbix能监视各种网络参数,保证服务器系统的安全运营:并提供灵活的通知机制以让系统管理员快速定位/解决存 ...

  9. NSFileManager 沙盒文件管理

    文件夹创建,复制,移动,删除,检查是否存在,代码如下: 1.获取沙盒 document 路径,作为文件夹路径的基路径. NSString *document = NSSearchPathForDire ...

  10. 1483:[HNOI]2009 梦幻布丁 - BZOJ

    Description N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1,2,2,1的四个布丁一共有3段颜色. Input 第 ...