Reputation: 39
It fails when it takes more than two digits....
Eg. Input: 0xf
Output: 15
But Input:0xFF
Output:-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
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:
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
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
andint
must be at least 16 bits wide, andlong
must be at least 32 bits wide, and thatsizeof (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
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