The following program gives the result as 0
instead of the expected decimal equivalent of the hexadecimal string constant.
#include <stdio.h>
int my_htoi(char[]);
int main(void) {
printf("%d", my_htoi("0xABC"));
return 0;
}
int my_htoi(char str[]) {
int i, num = 0;
for (i = 0; i != '\0'; ++i) {
if (str[i+1] == 'x' || str[i+1] == 'X') {
i = i + 1;
continue;
}
if (str[i] >= '0' && str[i] <= '9') {
num = num * 16 + (str[i] - '0');
} else if (str[i] >= 'a' && str[i] <= 'f') {
num = num * 16 + (str[i] - 'a' + 10);
} else if (str[i] >= 'A' && str[i] <= 'F') {
num = num * 16 + (str[i] - 'A' + 10);
}
}
return num;
}
While the following program runs fine and outputs the correct decimal equivalent of the hexadecimal string constant.
#include <stdio.h>
#include <string.h>
int my_htoi(char[]);
int main(void) {
printf("%d", my_htoi("0xABC"));
return 0;
}
int my_htoi(char str[]) {
int i, num = 0;
for (i = 0; i < strlen(str); ++i) {
if (str[i+1] == 'x' || str[i+1] == 'X') {
i = i + 1;
continue;
}
if (str[i] >= '0' && str[i] <= '9') {
num = num * 16 + (str[i] - '0');
} else if (str[i] >= 'a' && str[i] <= 'f') {
num = num * 16 + (str[i] - 'a' + 10);
} else if (str[i] >= 'A' && str[i] <= 'F') {
num = num * 16 + (str[i] - 'A' + 10);
}
}
return num;
}
The only difference is in the way we find the qualifying condition for the loop. Why does it not work with the null byte checking?
There are some problems in your code:
the loop index i
is compared to '\0'
instead of str[i]
, causing immediate termination of the loop with a return value of 0
.
the test for x
is incorrect: it would cause "1x2"
to convert to 2
instead of 1
.
you accept letters beyond f
and convert them to digits. The function should instead stop parsing at the first character that is not a hex digit.
Here is a corrected version:
#include <stdio.h>
int my_htoi(const char[]);
int main(void) {
printf("%d", my_htoi("0xABC"));
return 0;
}
int my_htoi(const char str[]) {
int i = 0, num = 0;
if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
i += 2;
for (; str[i] != '\0'; ++i) {
if (str[i] >= '0' && str[i] <= '9') {
num = num * 16 + (str[i] - '0');
} else if (str[i] >= 'a' && str[i] <= 'f') {
num = num * 16 + (str[i] - 'a' + 10);
} else if (str[i] >= 'A' && str[i] <= 'F') {
num = num * 16 + (str[i] - 'A' + 10);
} else {
break;
}
}
return num;
}