Exercise 2-3

Write the function htoi(s), which converts a string of hexadecimal digits (including an optional 0x or 0X) into its equivalent integer value. The allowable digits are 0 through 9, a through f, and A through F.

We can use atoi as a template for our function.

    /* atoi:  convert s to integer */
    int atoi(char s[])
    {
        int i, n;
    
        n = 0;
        for (i = 0; s[i] >= '0' && s[i] <= '9'; ++i)
            n = 10 * n + (s[i] - '0');
        return n;
    }

In atoi, every digit that is read in is multiplied by ten because, in base-ten, the place values are powers of ten. Since we are converting to hexadecimal, we will need to multiply by sixteen.

To deal with the digits a to f, we change the condition of the loop so it runs until the string terminates, and we also make sure to convert the character to lowercase using the function tolower so that uppercase characters work as well. The digits a to f have the value digit - 'a' + 10. Finally, after the loop has terminated, if the first character—s[0]—is a minus, we return -n instead.

    /* htoi:  convert a string of hex digits into an int */
    int htoi(char s[])
    {
        int i, n;
    
        for (i = n = 0; (s[i] = tolower(s[i])) != '\0'; ++i) {
            if (isdigit(s[i]))
                n = 16 * n + (s[i] - '0');
            else if (s[i] >= 'a' && s[i] <= 'f')
                n = 16 * n + (s[i] - 'a' + 10);
        }
        if (s[0] == '-')
            return -n;
        else
            return n;
    }

Note: our code can accept 0x because the initial zero does not change n at all, and characters that are not digits are ignored.