I\'m learning C and I can\'t figure out one of the K&R exercises, the listing:
Exercise 2-3, Write the function
htoi(s)
, which conv
Recursion is not necessary. You simply need to loop backwards over the string (i.e. starting in the units column), summing the single digit conversion times it's radix position multiplier. This is pseudocode and does not handle the optional 0x prefix (and is not checking for possibility of overflow):
long total = 0;
long multiplier = 1;
for (int i = string.length - 1; i >= 0 i--)
{
digit = ConvertSingleHexDigittoInt(string[i]);
total += digit * multiplier;
multiplier *= 16;
}
I've left the easy implementation of ConvertSingleHexDigittoInt() to you :)
A conventional approach converts from left to right. An accumulator is set to zero at the beginning, and multiplied by 16 before adding the equivalent value of each new digit to the loop.
For an htoi()
function that expects hexidecimal digits with an optional leading 0x
, begin by skipping past those characters if present. Directly checking the values of s[0]
and s[1]
is probably the clearest approach there.
If you know the digits are in ASCII, then you can use expressions like s[i] - '0'
and s[i] - 'A' + 10
to convert the i-th digit to its integer value.
You probably want to fold the whole thing to one case for sanity.
Edit: Changed *s
to s[i]
for consistency with the observation that pointers are from the future from the point of view of this exercise.
Note that there are several other ways to convert the individual digits to values. For example, you could look them up in a vector of all digits (something like strchr("0123456789ABCDEF",s[i])
), build a single lookup table indexed by character code with the value of each digit at each position (digitvalue[s[i]]
after int digitvalue[256]
has been suitably initialized), use a switch (s[i])
statement with a case
label for each possible digit as suggested in another answer, or use the range checks and arithmetic as I suggest above. Something to think about is which to choose, and why. Notice that it may not be an obvious choice, and the best answer may be different if ASCII is not your character set of choice.