itoa'd you so?

Charles Curley charlescurley at charlescurley.com
Wed Sep 19 21:04:09 MDT 2007


On Wed, Sep 19, 2007 at 02:42:25PM -0600, Steve wrote:

> Here is the setup.
> 
> There is no standard way to convert an int into a char*, or at least
> there is nothing in the standard library.
> 
> So I was asked how I would write an itoa function.
> The goal was to target an embedded platform, and so clock cycles and
> overhead really count.
> 
> The solution could be in either C or C++

I haven't written this in about eighteen years or so, and most of that
was in Forth or assembler. So it took me an hour to come up with a
pure C function with a test frame, and comment it. Some of that was
remembering how to do this in C.

As other folks have noted, the examiner didn't mention which base to
use. This is a general solution: any reasonable base and a lot of
unreasonable ones can be specified by setting the variable base. Doing
so I will leave as an exercise for the student.

As noted below, I am assuming a pure ASCII environment: no unicode, no
code pages. This would also work in a half-ASCII environment, i.e. no
lower case and no non-printing characters. (Yes, I've actually worked
on such a beastie.) What, if any, changes are necessary I will also
leave to the student.

I will also leave several optimizations I can think of to the student.

--------------------------------------------------
/* A subroutine to convert an int to a string representation
 * thereof. */

/* Time-stamp: <2007-09-19 20:52:54 ccurley itoa.c> */

/* These should be available in most imbedded systems. stdio.h is
 * only needed for the test frame anyway. */
#include <stdio.h>
#include <string.h>

#define SIZE sizeof (int)*2


/* TO DO: Add getopts, etc, so the user can set the base and test
 * value. */
int base = 16;

int test = 0xffffffff;

/* We depend on a pure ASCII environment here. */
char digit (int d)
{
    char ret = '0';

    ret += d;

    /* For bases greater than 10, skip from '9' to 'A' in the ASCII
     * table. This may have been a trick your examiner was looking
     * for. */
    if (ret > '9') {
        ret += 7;
    }
    return (ret);
}

char *itoa (int value, char *buffer)
{
    int i = 0;
    char tmp[SIZE+1];

    tmp[SIZE] = 0;

    /* For negative numbers, set the sign. Having done that, do the
     * conversion as a positive number. */
    if (value < 0) {
        strcat (buffer, "-");
        value = 0 - value;
    }

    while (value) {
        i++;

        /* Since we are starting at the right end of the string, we
         * fill our temporary buffer from the right. This is likely
         * another trick the examiner wanted. */
        tmp[SIZE-i] = digit (value%base);
        value = value/base;
    }

    /* I have no way of knowing the size of the incoming buffer, so I
     * have to build in a buffer, then copy into the given
     * one. strcat is likely more efficient and faster than strncat,
     * and probably coded in assembler. */
    strcat (buffer, &tmp[SIZE-i]);
}

main (int argc, char *argv[])
{
    char buffer[23];

    buffer[0] = 0;              /* Force buffer to hold a string of
                                 * length 0. Likely another trick the
                                 * examiner wanted. */

    printf ("%s, a program to exercise a subroutine to convert an int to a string.\n",
            argv[0]);

    printf ("0x%x converts to a string as %s.\n", test, itoa (test, buffer));
}
--------------------------------------------------

-- 

Charles Curley                  /"\    ASCII Ribbon Campaign
Looking for fine software       \ /    Respect for open standards
and/or writing?                  X     No HTML/RTF in email
http://www.charlescurley.com    / \    No M$ Word docs in email

Key fingerprint = CE5C 6645 A45A 64E4 94C0  809C FFF6 4C48 4ECD DFDB
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://plug.org/pipermail/plug/attachments/20070919/36583d87/attachment.bin 


More information about the PLUG mailing list