簡體   English   中英

C程序將十六進制轉換為整數

[英]C program to convert hexadecimal to integer

超過兩位數時失敗。...

例如。 輸入: 0xf輸出: 15
但是輸入: 0xFF輸出: -1

char s[20],hexdigit=0,i=0,deci=0;
scanf("%[^\n]",s);
if(s[0]=='0' && (s[1]== 'X' || s[1]=='x'))
    i=2;
for(;s[i]!='\0';i++){

    if(s[i]>='0' && s[i]<='9')
        hexdigit=s[i]-'0';
    else if(s[i]>='a' && s[i]<='f')
        hexdigit=s[i]-'a'+10;
    else if(s[i]>='A' && s[i]<='F')
        hexdigit=s[i]-'A'+10;
    else
        break;
    deci=(16*deci)+hexdigit;
}
    printf("\n%d",deci);  

系統上的char類型只能存儲-128+127之間的+127 要獲得更大的范圍,請使用其他數據類型。

代替

char deci = 0;

int deci = 0;

這種類型也會溢出,但是要晚得多。 通常為2147483647。當您嘗試解析任何較大的值時,該行為是undefined

您可以通過寫進一步的內容

unsigned int deci = 0;

此類型將在4294967295處溢出,然后它將再次從0開始。此處沒有未定義的行為。

您正在使用只能存儲-128+127之間的值的char 而是使用其他數據類型來獲得更大的范圍。

所以代替

  char deci = 0;

使用int

  int deci  = 0;   

即使溢出,您也可以使用unsigned int (因為您的代碼僅讀取非負值)

  unsigned int = 0;

C標准保證char必須至少為8位寬, shortint必須至少為16位寬, long必須至少為32位寬,並且sizeof (char) <= sizeof (short) <= sizeof (int) <= sizeof (long)這些類型的無符號版本也是如此)。

根據平台的不同, int寬度可能在16到64位之間。

另外,您的代碼還有另一個問題,可能會導致將來執行時出錯。

您的數組下標ichar並且編譯器應該給了您

警告:數組下標的類型為'char'。

之所以如此,是因為char類型可以是有符號的也可以是無符號的,這取決於編譯器。 如果對char進行了簽名,則i可能為負,在這種情況下訪問負數組索引會導致未定義行為。 我強烈建議您查看此答案 ,以免將來遇到常見的陷阱。

提示:始終正確格式化代碼,這將有助於您可視化代碼,也可以幫助其他試圖在其中發現問題的人。

Downvoter Care解釋為什么他拒絕投票。

首先,轉換時必須考慮十六進制的表示方式。 它是小的endian,因此您必須從字符串的最右邊開始。

接下來,您必須考慮到,在每個步驟中,十六進制轉換都將需要以16為底的冪(因為這是十六進制的平移)。

之后,您必須確定如何從另一個中減去ASCII表示形式(僅二進制),例如:

  1. 'E'-'A'將產生1110(E)-1010(A)= 0100(4或減法的十進制值)
  2. 由於范圍AF的十進制偏移量增加了10:0100(EA)+ 1010(10)= 14
  3. 乘以16的基本乘方到給定位置(so 0)

然后,我們可以在每種情況下應用此算法來獲取十六進制轉換。 代碼看起來像這樣:

#include <stdio.h>
#include <math.h>
int htoi(char s[]);
int my_strlen(char s[]);


int main(int argc, char **argv) {
    unsigned long int val;
    val = htoi("0x4E"); //Check N
    if (val > 0)
        printf("Value val: %lu", val);
    else
        printf("improperly formatted");
    return 0;
}

//Coded for example
int htoi(char s[]) {
    int i, j;
    unsigned long int z;
    i = z = 0;
    j = my_strlen(s) - 1;

    if(j < 2) return z;
    if (s[i++] != '0') return z;
    if (s[i] != 'X' && s[i] != 'x') return z;

    //Reset i to represent position
    i = 0;
    //Convert hexidecimal to integer
    for(i = 0; s[j] != 'x' && s[j] != 'X'; j--, i++) {
        if(s[j] >= '0' && s[j] <= '9')
            z =  z + (s[j] - '0') * pow(16, i);
        else if(s[j] >= 'a' && s[j] <= 'f')
            z = z + ((s[j] - '0') + 1) * pow(16, i);
        else if(s[j] >= 'A' && s[j] <= 'F')
            z = z + ((s[j] - 'A') + 10) * pow(16,i);
        else
            continue;
    }
    return z;
}

//Coded for example
int my_strlen(char s[]) {
    int i = 0;
    while(s[i] != '\0')
        i++;
    return i;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM