Write Your Own Integer Conversion – Solution

This month’s Exercise is to emulate the antique atoi() function, which converts a string of digits into an integer value.

One of the built-in frustrations of this type of conversion is that strings are read left-to-right and values are interpreted right-to-left. I didn’t initially see the brilliance of a left-to-right solution, so for my first solution I crafted the convert() function to process the string backwards in a for loop:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

int convert(char *s)
{
    int len,x,r;

    len = strlen(s);
    for( x=0, r=0; x<len; x++ )
    {
        r += ( *(s+len-x-1) - '0' ) * pow( 10.0, (double)x );
    }

    return(r);
}

int main()
{
    char value[] = "345966";
    int v;

    v = atoi(value);
    printf("%s from atoi() is %d\n",value,v);
    v = convert(value);
    printf("%s from convert() is %d\n",value,v);

    return(0);
}

The for loop at Line 11 has two initializations, x the counting variable and r the total to return from the function.

The complex evaluation at Line 13 increases the value of variable r first by the left-most digit in the string, calculated as *(s+len-x-1). The value '0' is subtracted from the character’s ASCII value, yielding an integer. This result is raised to the power of 10 based on the value of x: pow(10.0,(double)x). The effect is that the integer’s value is increased for each position right-to-left in the string.

Honestly, I must have been seriously nerdy when I thought of this solution. Yet, for all its clunky math, it works. Here’s the output:

345966 is 345966
345966 is 345966

For my second solution, I fought to process the string left-to-right. I had a similar notion about how the math would work, but the result turned out to be far more elegant than my first stab at a solution:

#include <stdio.h>
#include <stdlib.h>

int convert(char *s)
{
    int r = 0;

    while( *s )
    {
        r = (r*10) + (*s-'0');
        s++;
    }

    return(r);
}

int main()
{
    char value[] = "345966";
    int v;

    v = atoi(value);
    printf("%s is %d\n",value,v);
    v = convert(value);
    printf("%s is %d\n",value,v);

    return(0);
}

The naked simplicity of Line 10 is appalling. The while loop processes the string left-to-right, variable s incremented at Line 11. For each iteration, the existing value of r is multiplied by 10 and the value of the current digit is added: (*s='0'). This process repeats until the string has been read and it yields a perfect result:

345966 is 345966
345966 is 345966

Because the string is processed left-to-right, I didn’t need to find churn through the entire string, find its end, or bring in the math library. By not over-thinking the solution, I came up with something sweet and elegant.

I hope your solution was more like my second and less like my first. Still, both solutions work. If your solution was able to convert the string into the proper value, congratulations.

3 thoughts on “Write Your Own Integer Conversion – Solution

  1. I agree, the second version is much more elegant.

    From memory I think atoi ignores leading whitespace, and finishes if it hits any non-digits so to replicate this you could continue (skip to the next iteration) if you start out with spaces and break out of the loop if there are any non-digits at the right.

    Obviously this somewhat detracts from the elegance of the solution. Such is life.

    Anybody not familiar with C would be baffled by this code. “He’s subtracting a character from another character, then incrementing the character. Must be mad!”

  2. You once mentioned on your other blog that you had been playing with a Raspberry Pi. I’ve just got back from a couple of days in Cambridge and since I was there last they have opened a Raspberry Pi store.

    https://www.raspberrypi.org/magpi/raspberry-pi-official-retail-store/

    I felt myself magnetically drawn to it as I have been trying to resist the temptation to buy one. If I did I would spend a huge amount of time I can’t really spare on it, neglecting trivial things like sleep and food. Managed to resist the goodies on show this time but I think one day I’ll probably crack!

  3. Alas, I have my “new” Raspberry Pi sitting at the far end of my workbench, configured and ready for me to play with. It’s been sitting there for TWO YEARS. *sigh*

Leave a Reply