Priyadharshini
Priyadharshini

Reputation: 39

C program to convert hexadecimal to integer

It fails when it takes more than two digits....

Eg. Input: 0xf Output: 15
But Input:0xFFOutput:-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);  

Upvotes: 0

Views: 3307

Answers (3)

JoshuaTPritchett
JoshuaTPritchett

Reputation: 1

First, when converting you must consider how hexadecimal is represented. It is little endian, thus you must start from the far right portion of the string.

Next, you must consider that at each step, the hex conversion will require base 16 (since this is the translation of hex) to the power of the position.

After that you must determine how to subtract the ASCII representation (just binary) from the other so for example:

  1. 'E' - 'A' will produce 1110(E) - 1010(A) = 0100(4 or decimal value of subtraction)
  2. Add 10 since decimal offset for range A-F: 0100 (E-A) + 1010 (10) = 14
  3. Multiply by the base power of 16 to the given position (so 0)

We then can apply this algorithm to get the hexadecimal conversion in every case. The code would look something like this:

#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;
}

Upvotes: 0

Suraj Jain
Suraj Jain

Reputation: 4536

You are using char which can only store values between -128 and +127. Instead Use other data type to get much alrger range.

So instead of

  char deci = 0;

use int

  int deci  = 0;   

and even if it overflows you can use unsigned int (As your code only reads non-negative values)

  unsigned int = 0;

C Standard guarantees that char must be at least 8 bits wide, short and int must be at least 16 bits wide, and long must be at least 32 bits wide, and that sizeof (char) <= sizeof (short) <= sizeof (int) <= sizeof (long) (same is true for the unsigned versions of those types).

int may be anywhere from 16 to 64 bits wide depending on the platform.

Also There is another problem with your code that could result in fault in execution in future.

Your array subscript i is char and compiler should have given you the

Warning : array subscript has type 'char'.

It has given so because type char can be signed or unsigned—it's up to the compiler. If char is signed, then it's possible for i to be negative, in which case accessing a negative array index leads to Undefined Behavior. I highly recommend you to look at this answer to avoid common pitfall in future.

Tip: Always Format Your Code Properly, it would help you in visualising and also to others who are trying to find problem in it.

Downvoter Care To Explain Why he downvoted.

Upvotes: 0

Roland Illig
Roland Illig

Reputation: 41617

The type char on your system can only store values between -128 and +127. To get a larger range, use another data type.

Instead of

char deci = 0;

write

int deci = 0;

This type will also overflow, but much later. Typically at 2147483647. When you try to parse any larger value, the behavior is undefined.

You can go one bit further by writing

unsigned int deci = 0;

This type will overflow at 4294967295, after which it will start again with 0. No undefined behavior here.

Upvotes: 5

Related Questions