1 /*
  2 atoi算法,要求完美版
  3 有两种,一种是用longlong,一种是真用int
  4 “”
  5 "  "
  6 “-”
  7 “+”
  8 “  -23”
  9 “  +23”
 10 “12a"
 11 "abc"
 12 越界情况
 13 */
 14 #include <iostream>
 15 using namespace std;
 16 
 17 //方法一用 long long 取巧
 18 int atoi(const char * str,bool & flag)
 19 {
 20     long long result=0;
 21     int tmp;
 22     int sign=1;
 23     if(str==NULL)
 24     {
 25         flag=false;
 26         return 0;
 27     }
 28     while(isspace(*str))
 29         str++;
 30     //if(*str=='\0')
 31     //{
 32     //    flag=false;
 33     //    return 0;
 34     //}
 35     if(*str=='+'||*str=='-')
 36     {
 37         if(*str=='-')
 38             sign=-1;
 39         str++;
 40     }
 41     if(*str=='\0')                     //”    “和”+“ ,”-“的情况
 42     {
 43         flag=false;
 44         return 0;
 45     }
 46     while(*str>='0'&&*str<='9')
 47     {
 48         tmp=*str-'0';
 49         result=result*10+tmp;
 50         if(sign==-1)
 51         {
 52             if(result-1>INT_MAX)           //这里注意,如果是INT_MAX+1,系统或默认转换成int,导致越界,所以用result-1,result是longlong不会越界
 53             {
 54                 result=INT_MAX+1;
 55                 flag=false;
 56                 break;
 57             }
 58         }
 59         else if(result>INT_MAX)
 60         {
 61             result=INT_MAX;
 62             flag=false;
 63             break;
 64         }
 65         str++;
 66     }
 67     if(*str=='\0')
 68         flag=true;
 69     else
 70         flag=false;
 71     return sign*result;
 72 }
 73 
 74 //方法二 用int
 75 int atoi2(const char * str ,bool & flag)
 76 {
 77     int result=0;
 78     int sign=1;
 79     int tmp;
 80     int MAX_DIV=INT_MAX/10;
 81     int MAX_R=INT_MAX%10;
 82     int MIN_R=MAX_R+1;   //或者为MIN_R=-(INT_MIN%10);    //如果用(INT_MAX+1)%10就错了,直接加的时候越界
 83     int MIN_DIV=(INT_MAX)/10;        
 84 
 85     //july用的是max=(int)((unsigned)~0>>1);
 86     //min_r=(int)(((unsigned)~0>>1+1)%10);
 87     if(str==NULL)
 88     {
 89         flag=false;
 90         return result;
 91     }
 92     while(isspace(*str))
 93         str++;
 94     if(*str=='+'||*str=='-')
 95     {
 96         if(*str=='-')
 97             sign=-1;
 98         str++;
 99     }
100     if(*str=='\0')
101     {
102         flag=false;
103         return result;
104     }
105     while(*str>='0'&&*str<='9')
106     {
107         int tmp=*str-'0';
108         if(sign==1)
109         {
110             if(result>MAX_DIV||(result==MAX_DIV&&tmp>MAX_R))
111             {
112                 result=INT_MAX;
113                 flag=false;
114                 return result;
115             }
116         }
117         else if(result>MIN_DIV||(result==MIN_DIV&&tmp>MIN_R))
118         {
119             result=INT_MIN;                                               //result直接为最小-2147483648,直接返回了
120             flag=false;
121             return result;
122         }
123         result=result*10+tmp;
124         str++;
125     }
126     if(*str=='\0')
127         flag=true;
128     else
129         flag=false;
130     return sign*result;
131 }
132 
133 
134 
135 int main()
136 {
137     char * str[]={""," ","abc","  123","  -1234","   +34","  12bc","+","-","+++","0","2147483647","+2147483648","-2147483648","-2147483649","+12123131312432342","   -122323434534534654"};
138     //cout<<INT_MAX<<endl;
139     int n=17;
140     bool flag;
141     for(int i=0;i<n;i++)
142     {
143         int tmp=atoi2(str[i],flag);
144         if(tmp==0)
145         {
146             if(flag==false)
147                 cout<<str[i]<<" 错误数据转换为: "<<tmp<<endl;
148             else
149                 cout<<str[i]<<" 转换为: "<<tmp<<endl;
150         }
151         else
152         {
153         cout<<str[i]<<" 转换为: "<<tmp<<endl;
154         }
155     }
156     system("pause");
157 }
 posted on 2014-07-24 22:35  zmlctt  阅读(293)  评论(0编辑  收藏  举报