itoa()

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
Whatever5k

itoa()

Post by Whatever5k »

I am currently writing my own vsprintf() function and nearly everything works. I handled strings (%s), but I have problems with integers (%d). I have a function itoa() (picked it from somewhere), but when I print the string out, there's only crap.
This is the code:

Code: Select all

/* vsprintf() - dissolve conversions */
void vsprintf(char *str, const char *format, va_list ap)
{
   char *p = str;
   char *s; int d; char c;
   int i = 0;
   int j=0;
   char buf[MAXLEN];
   
   *p = '\0';
   /* go through format until we reach a % */
   while (*format != '\0')
   {
      if (*format != '%')   /* ordinary character */
      {
         i = strlen(p);
         p[i] = *format;
         p[i + 1] = '\0';
      }
      
      else
      {
         switch (*(format + 1))
         {
            case 'c':   /* char */
               c = (char) va_arg(ap, int);
               i = strlen(p);
               p[i] = c;
               p[i + 1]  = '\0';
               break;      
            case 's':   /* string */
               s = va_arg(ap, char *);
               strcat(p, s);
               break;
            case 'd':   /* integer */
            case 'i':
               d = va_arg(ap, int);
               itoa(d, buf, 10);   /* convert to string */
               while (buf[j] != '\0')
                  putc(buf[j++]);
               strcat(p, buf);
               break;
            default:
               /* print the % and the following character */
               i = strlen(p);
               p[i]  = *format;
               p[i + 1]  = *(format + 1);
               p[i + 2]  = '\0';
               break;
         }
         format++;
      }
      format++;
   }
}            
And this here is the itoa() function:

Code: Select all

void reverse(char *s)
{
   char *j;
   int i = strlen(s);

   strcpy(j,s);
   while (i-- >= 0)
      *(s++) = j[i];
   *s = '\0';
}

/* itoa()
 * converts an integer into a string */

void itoa(int n, char *buffer, int base)
{
   char *ptr = buffer;
   int lowbit;

   base >>= 1;
   do
   {
      lowbit = n & 1;
      n = (n >> 1) & 32767;
      *ptr = ((n % base) << 1) + lowbit;
      if (*ptr < 10)
         *ptr +='0';
      else
         *ptr +=55;
      ++ptr;
   }
   while (n /= base);
   *ptr = '\0';
   reverse (buffer);   /* reverse string */
}
As already said: when I try to

printf("I'm %d years old\n", 20);

the number (20) and a smiley is print on the screen, what is definetely wrong...
S.o. sees the bug?
Anonymous

Re:itoa()

Post by Anonymous »

Forgot putc in if (*format != '%') /* ordinary character */ to output character
Dave_Hunt

Re:itoa()

Post by Dave_Hunt »

In the reverse() function you have:

char *j;
...
strcpy(j,s);

j does not have any spaces and points to whatever is on the stack at the location of j. You're lucky you're just getting crap and not dumping core.

Try changing

char *j;

to

char j[20]; /* or whatever size you want */

Also, in vsprintf(), you have

...
while (buf[j] != '\0')
...

But j is only initialized to zero on entry into vsprintf. If you have multiple '%d' specs in your format string, the second and subsequent executions of the above while loop will pick up at the current value of j. This will undoubtedly result in additional crap in your output string.
Post Reply