实现aoti() 函数
2015-09-09 20:53
369 查看
看到一到题目,要自己实现atoi()函数,标准库里的atoi 是这样要求的:
参数nptr字符串,如果第一个非空格字符存在,是数字或者正负号则开始做类型转换,之后检测到非数字(包括结束符
\0) 字符时停止转换,返回整型数。否则,返回零。
而且还得考虑溢出的问题。
我自己尝试了一下,跟网上大神的对比,我的逻辑不够清晰,估计只能自己看得懂。大神用的是C++,除了输入输出函数C不同外,其余代码都兼容C。
先放大神的代码:http://www.cnblogs.com/pangxiaodong/archive/2011/06/17/2083471.html
最后是我的,目前还没看到什么bug:
参数nptr字符串,如果第一个非空格字符存在,是数字或者正负号则开始做类型转换,之后检测到非数字(包括结束符
\0) 字符时停止转换,返回整型数。否则,返回零。
而且还得考虑溢出的问题。
我自己尝试了一下,跟网上大神的对比,我的逻辑不够清晰,估计只能自己看得懂。大神用的是C++,除了输入输出函数C不同外,其余代码都兼容C。
先放大神的代码:http://www.cnblogs.com/pangxiaodong/archive/2011/06/17/2083471.html
#include<iostream> using namespace std; int my_atoi(const char *str) { if(str == NULL) throw "str == NULL!"; enum STATE {STATE_SKIP_SPACE, STATE_RECOGNIZE_SIGN, STATE_RECOGNIZE_NUM, STATE_RECOGNIZE_LAST_NUM, STATE_RECOGNIZE_TAIL_CHAR}; STATE state = STATE_SKIP_SPACE; int max = INT_MAX; int min = INT_MIN; int bound = max / 10; int sign = 1; unsigned int result = 0; bool find_num = false; while(true) { switch(state) { case STATE_SKIP_SPACE: // 跳过尽可能多的空格 if(*str==' '||*str=='\t'||*str=='\n'||*str=='\f'||*str=='\b'||*str=='\r') str++; else state = STATE_RECOGNIZE_SIGN; break; case STATE_RECOGNIZE_SIGN: // 识别可能的正负符号 if(*str == '-') { str++; sign = -1; } else if(*str == '+') { str++; } state = STATE_RECOGNIZE_NUM; break; case STATE_RECOGNIZE_NUM: // 最多识别max/10的位数的数字 if(*str <'0' || *str>'9' || *str=='\0') // 当前字符不是数字,或者已经结束 if(find_num == false) // 一个数字都还没遇到过 throw "no num found!"; else // 已经遇到过数字了 return result * sign; else { // 当前字符是数字 if(find_num == false) find_num = true; result *= 10; result += (*str-'0'); bound /= 10; if(bound ==0) { state = STATE_RECOGNIZE_LAST_NUM; } str++; } break; case STATE_RECOGNIZE_LAST_NUM: // 识别最后一个数字 if(*str <'0' || *str>'9' || *str=='\0') // 当前字符不是数字,或者已经结束 return result * sign; // 能到这一步,肯定是已经遇到了很多数字 else { // 当前字符是数字 if((result > max/10) || (sign==1 && (*str-'0')>(max%10)) || (sign==-1 && (*str-'0')>abs(min%10))) { throw "over num limit !"; } else { result *= 10; result += (*str - '0'); state = STATE_RECOGNIZE_TAIL_CHAR; str++; } } break; case STATE_RECOGNIZE_TAIL_CHAR: // 不能再识别数字了 if(*str <'0' || *str>'9' || *str=='\0') // 当前字符不是数字,或者已经结束 return result * sign; else // 当前字符是数字,此时必然溢出 throw "over num limit !"; break; default: break; } } return 0; } int main() { char* a = " +123213123abc"; char* max = " 2147483647abc"; char* min = " -2147483648abc"; char* max_more_1 = " 2999999997abc"; char* max_more_2 = " 2147483648abc"; char* min_more_1 = " -2147483649abc"; cout << a << ": " << my_atoi(a) << endl; cout << max << ": " << my_atoi(max) << endl; cout << min << ": " << my_atoi(min) << endl; try { cout << max_more_1 << ": "; my_atoi(max_more_1); } catch (const char* info){ cout << info << endl; } try { cout << max_more_2 << ": "; my_atoi(max_more_2); } catch (const char* info){ cout << info << endl; } try { cout << min_more_1 << ": "; my_atoi(min_more_1); } catch (const char* info){ cout << info << endl; } char wait; cin >> wait; return 0; }
最后是我的,目前还没看到什么bug:
/********************************************************************************* * Copyright: (C) 2015 zq979999<zq979999@outlook.com> * All rights reserved. * * Filename: myatoi.c * Description: This file * * Version: 1.0.0(2015年09月09日) * Author: zq979999 <zq979999@outlook.com> * ChangeLog: 1, Release initial version on "2015年09月09日 11时37分15秒" * ********************************************************************************/ #include <limits.h> #include <stdio.h> #include <string.h> int myatoi(char string[]); void main(void) { int i; int result; char teststring[][30] = {"akf-2147483648",\ "fjlsd+214748365ddd",\ "sdfsd12345678900ds",\ "fdsfk+12345678900",\ "fsdf+2147483649",\ "sdfs000000000",\ "-1",\ "ffsdf00000001fdf",\ "\0",\ "FFFFFFFfffFFFF"}; for( i = 0; i < (sizeof(teststring) / sizeof(teststring[0])); i++ ) { result = myatoi( teststring[i] ); printf( "the result is %d\n", result ); } } int myatoi(char string[]) { int int_max_len = 0; int int_max = INT_MAX; int num_len = 0; char *str = string; int result_num = 0; enum flags{NO_NUM, GET_NUM, OVFLW}flag; int sign = 1; flag = NO_NUM; if(!string) return 0; while( 1 ) { int_max = int_max / 10; int_max_len++; if( int_max == 0 ) break; } while( *str != 0 ) { if( *str < '0' || *str > '9' ) { if( flag == GET_NUM ) { result_num = result_num * sign; return result_num; } str++; } else { if( flag == NO_NUM && *( str - 1 ) == '-' ) sign = -1; flag = GET_NUM; num_len++; if( num_len >= int_max_len ) //已经计算到允许的最大数字长度 { if( result_num > ( INT_MAX / 10) ) //已经存在的数字比最大值的十分之一还要大,那无论如何都会溢出 { flag = OVFLW; goto ERROR; } else if( result_num == ( INT_MAX / 10 ) &&\ ( *str - '0' ) > ( sign == 1 ? ( INT_MAX % 10 ):( INT_MAX % 10 + 1 ) ) ) { flag = OVFLW; goto ERROR; } else { result_num = result_num * 10; result_num = result_num + ( *str - '0' ); } } <span style="white-space:pre"> </span> else <span style="white-space:pre"> </span> { result_num = result_num * 10; result_num = result_num + ( *str - '0' ); <span style="white-space:pre"> </span> } str++; } } if( flag == NO_NUM ) { printf("no number\n"); return 0; } result_num = result_num * sign; return result_num; ERROR: if( sign == 1 ) { printf( "error:higher than INT_MAX : %d\n", INT_MAX ); return 0; } else { printf( "error:lower than INT_MIN : %d\n", -INT_MAX-1 ); return 0; } }
相关文章推荐
- 自定义视图、使用视图控制器知识点总结
- 关于学生管理系统的简单操作(数据库应用)
- CSAPP读书笔记——程序的机器级表示之条件跳转与循环
- Scalaz(3)- 基础篇:函数概括化-Generalizing Functions
- 2016华为机试题目:最大的凸多边形
- Scalaz(3)- 基础篇:函数概括化-Generalizing Functions
- 0909 几种控件(1) 蓝懿
- iOS—实现UI imageview的底层
- Android之VideoView播放视频
- [leetcode] Multiply Strings
- MySQL的特点
- Expression Tree Build
- string.length()与-1比较为什么会出现匪夷所思的结果
- 解决虚拟机Ping不同物理主机的问题-----在桥接模式下
- matlab基础学习——数组
- 【JZOJ】4211 送你一棵圣诞树
- POJ - 1287 Networking(最小生成树)
- S3C2410/S3C2440 NAND Flash
- Spring quartz 任务调度(注解方式)
- android studio命令大全