Page 1 of 1

itoa()

Posted: Sun Sep 22, 2002 6:38 am
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?

Re:itoa()

Posted: Sun Sep 22, 2002 11:42 am
by Anonymous
Forgot putc in if (*format != '%') /* ordinary character */ to output character

Re:itoa()

Posted: Mon Sep 23, 2002 9:08 am
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.