您的位置:首页 > 其它

实现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

#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;
    }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: