1. 程式人生 > >字串轉int:處理8,10,16進位制以及處理無效字元

字串轉int:處理8,10,16進位制以及處理無效字元

字串轉int函式:

函式名:Myatoi(*str)

功能:將一串字串轉成int整形數字

注意事項:

1.int型最大取值範圍:2147483647,int型佔4位元組,即4*8 = 32位二進位制,整數在二進位制中用原碼錶示即可,第一位為符號位0表示正數,即:01111111 11111111 11111111 11111111,十六進位制(HEX)表示為:0fff ffff,十進位制計算方法為:2^31 – 1;最小值:十六進位制為:0x80000 0000(HEX),二進位制為:10000000 00000000 00000000 00000000(BIN),十進位制計算方法為:-1*2^31。

2.程式設計時,我第二次用了分開計算正數和負數的方法。由於第一次計算正數,得出負數時是把sum × (-1),這樣計算就會有bug。因為正數的最大值為2147483647,所以×(-1)得到的負數最小值為-2147486947,而不是0x8000 0000(HEX)。

3.注意int型別和char型別一樣是,表示的範圍是迴圈的,我們知道char類型範圍是:-128  — 127 ,如果char a = 127,b = a+1;那麼b就為-128;

所以int同理,我們可以用sum>0或者sum<0判斷sum是否超出的正數或者負數的表示表示範圍。例如:我們求sum為整正數,sum = sum*10 +*str – ‘0’,此時sum為2147483647,sum再加一個1 ,就超出了int表示的正數範圍,2147483647 + 1 為 -2147483648 ,這是一個負數了,此時sum<0,所以sum = MAXINT(最大int正數)。

同理sum表示負數時,若sum一直減,減到最小後再減就>0了,此時就可以退出迴圈,sum = MININT就ok了。

4.先寫了10進位制的情況;十六進位制和八進位制的情況,不需要像10進位制一樣考慮 負號和正號。

5.用到的幾個字元函式:

    isdigit();//判斷字元是否為數字

    isxdigit();//判斷引數字元是否為16進位制字元,即A-F,a-f

    toupper();//如果引數字元是小寫字母,則轉化成大寫字母

       6.將字元轉化為int整數時候:

              如果是數字字元,’a’ – ‘0’ 減字元0即可。

              如果是字母,‘B’ – ‘A’ +10;//表示11。16進位制的計算時要用到

        7.還有一個問題:十六進位制和八進位制的sum判斷是否超出範圍,在定義sum時將其定義為long long型別,進行加法加法運算時候,if(sum >maxint),就退出迴圈,返回maxInt。再將最後的結果轉化為int型別。

程式用例:

#include<ctype.h>

#include<assert.h>

#include<stdio.h>

 

#define MAXINT  0x7fffffff //int範圍內的最大正數

#define MININT  0x80000000 //最小的負數

 

int Str_To_Int_DEC(char *str)//10進位制

{

   int sum = 0;

   int flag = 1;//判斷正負數 1表示正數 -1 表示負數

   bool first_sum = true;//做負數運算時 判斷第一次運算是否執行

   while(*str == ' ')

   {

      str++;

   }

   if(*str == '-')

   {

      flag = -1;

      str++;

   }

   else if(*str == '+')

   {

      str++;

   }

   while(isdigit(*str))

   {

      if(flag == 1)

      {

        sum = sum*10 + *str -'0';

        str++;

        if(sum < 0)

        {

           return MAXINT;

        }

      }

      else if(flag == -1)

      {

        if(first_sum == true)

        {

           sum = -(*str-'0');//第一個數為負數

           str++;

           first_sum = false;

        }

        else if(first_sum == false)

        {

           sum = sum*10 - (*str - '0');

           str++;

        }

        if(sum > 0)

        {

           return MININT;

        }

      }

   }

   return sum;

}

 

int Str_To_Int_HEX(char *str)//16進位制
{
    long long sum = 0;
    while(*str == ' ')
    {
        str++;
    }
    while(isxdigit(*str))//int isxdigit();功能:如果引數是十六進位制數字字元(即:A-F, a-f, 0-9),函式返回非零值,否則返回零值。
    {
        if(isalpha(*str))
        {
            sum = sum*16 + toupper(*str) -'A'+10;//如果是字母的話
            str++;
        }
        else if(isdigit(*str))
        {
            sum = sum*16 + *str -'0';
            str++;
        }
        if(sum > MAXINT)
        {
            sum = MAXINT;
            break;
        }
    }
    return (int)sum;
}
int Str_To_Int_OCT(char *str)//8進位制
{
    long long sum = 0;
    while(*str == ' ')
    {
        str++;
    }
    while(*str>= '0' && *str <= '7')
    {
    
        sum = sum*8 + *str -'0';
        str++;
        if(sum > MAXINT)
        {
            sum = MAXINT;
            break;
        }
    }
    return (int)sum;
}

 

int Myatoi(char *str)

{

   assert(str != NULL);

   int result;

   while(isspace(*str))

   {

      str++;

   }

   if(*str == '0')

   {

      str++;

      if(*str == 'x' || *str == 'X')

      {

        str++;

        result = Str_To_Int_HEX(str);

      }

      else

      {

        result = Str_To_Int_OCT(str);

      }

   }

   else

   {

      result = Str_To_Int_DEC(str);

   }

   return result;

}

 

int main()

{ 

   char *str1 = "321564";

   char *str2 = "2147483647";

   char *str3 = "2147483648";

   char *str4 = "+326549875646156";

   char *str5 = "-321564";

   char *str6 = "-2147483648";

   char *str7 = "-2147483649";

   char *str8 = "0x7fffffff";

   char *str9 = "80000000";

   char *str10 = "0x654ab";

   char *str11 = "0Xbbb";

   printf("%d\n", Myatoi(str1));

   printf("%d\n", Myatoi(str2));

   printf("%d\n", Myatoi(str3));

   printf("%d\n", Myatoi(str4));

   printf("%d\n", Myatoi(str5));

   printf("%d\n", Myatoi(str6));

   printf("%d\n", Myatoi(str7));

   printf("%d\n", Myatoi(str8));

   printf("%d\n", Myatoi(str9));

   printf("%d\n", Myatoi(str10));

   printf("%d\n", Myatoi(str11));

   return 0;

}

 

下面是十進位制的測試結果: