Con le seguenti funzioni è possibile trasformare un numero nella stringa corrispondente. Sono presentate le funzioni _itoa(), _ltoa(), _ultoa(), _ftoa() per convertire rispettivamente tipi int, long, unsigned long, e float in stringhe. La scelta di anteporre un underscore ( _ ) prima del nome della funzione è reso necessario dal fatto che queste sono automaticamente supportate da alcuni compilatori, quindi se programmate per esempio in Turbo C non c’è bisogno di inserirle nel vostro programma (Consultate le referenze del vostro compilatore per conoscere se sono supportate o meno). L’utilizzo di _itoa(), _ltoa() e _ultoa() è simile in quanto sostanzialmente fanno tutte da wrapper tramite casting alla funzione xtoa() che esegue il lavoro reale. Per quanto riguarda _ftoa() la chiamata differisce in quanto invece di passare la radice di conversione bisogna passare la precisione dei numeri prima e dopo la virgola.

Entriamo nei dettagli:

I parametri per le funzioni _itoa(), _ltoa() e _ultoa() sono val (il numero da convertire, rispettivamente di tipo int, long oppure unsigned long. Il buffer precedentemente allocato in cui salvare i risultati, la radice ovvero la base su cui effettuare la conversione (per il decimale è 10, per l’esadecimale 16 per l’ottale 8, ecc…).

Tutte ritornano un puntatore al buffer passato.

static void xtoa (unsigned long val,char *buf,
                  unsigned radix,int is_neg)  {
  char *p;    /* pointer to traverse string */
  char *firstdig;   /* pointer to first digit */
  char temp;    /* temp char */
  unsigned digval;  /* value of digit */

  p = buf;

  if (is_neg) {
    /* negative, so output '-' and negate */
    *p++ = '-';
    val = (unsigned long)(-(long)val);
  }

  firstdig = p;  /* save pointer to first digit */

  do {
    digval = (unsigned) (val % radix);
    val /= radix;   /* get next digit */

    /* convert to ascii and store */
    if (digval > 9)
      *p++ = (char) (digval - 10 + 'a');  /* a letter */
    else
      *p++ = (char) (digval + '0');       /* a digit */
  } while (val > 0);  /* We now have the digit of the number in the buffer,
     but in reverse order.  Thus we reverse them now. */

  *p-- = '\0';    /* terminate string; p points to last digit */

  do {
    temp = *p;
    *p = *firstdig;
    *firstdig = temp;   /* swap *p and *firstdig */
    --p;
    ++firstdig;   /* advance to next two digits */
  } while (firstdig < p); /* repeat until halfway */
}

/* Actual functions just call conversion helper with neg
   flag set correctly,
   and return pointer to buffer. */

char * _itoa (int val,char *buf,int radix)    {
  if (radix == 10 && val < 0)
    xtoa((unsigned long)val, buf, radix, 1);
  else
    xtoa((unsigned long)(unsigned int)val, buf, radix, 0);
  return buf;
}

char * _ltoa (long val,char *buf,int radix)   {
  xtoa((unsigned long)val, buf, radix, (radix == 10 && val < 0));
  return buf;
}

char * _ultoa (unsigned long val,char *buf,int radix)   {
  xtoa(val, buf, radix, 0);
  return buf;
}

Qui invece viene presentata la funzione _ftoa() che come anticipato prima differisce nei parametri passati; infatti essa richiede come primo argomento il solito val in formato float ovvero il numero da convertire, come secondo e terzo parametro la precisione da utilizzare nella conversione (Attenzione m deve essere comunque minore di 15 e n minore di 12), e a invece è il buffer dove saranno inseriti i risultati. Notate che la lunghezza di a sarà proprio uguale a n+m+2. Anch’essa ritorna un puntatore al buffer passato.

#include <math.h>

int _ftoa(float val, int n, int m, char *a)
{
  int i, j, b[15], c[15];
  char sign= ' ';
  double x;

  if (n > 15 || m > 12)
   return(0);
  n = n-m-2;

  if (val < 0) {
    val = -val;
    sign= '-';
  }
  while (val > pow(10.,(double)n))
    ++n;
  if (n > 15)
   return(0);

  for (i = n-1; i > 0; --i)
  {
    x = pow(10.,(double)i);
    b[n-1-i] = val/x;
    val -= (float)b[n-1-i]*x;
  }
  b[n-1-i] = val;
  val -= (float)b[n-1-i];
  val = val * pow(10.,(double)m);
  val = (float)(floor(2*val) -  (int)val);
  for (i=m-1; i > 0; --i) {
    x = pow(10.,(double)i);
    c[m-1-i] = val / x;
    val -= (float)c[m-1-i]*x;
    if (c[m-1-i] == 10) {
      c[m-1-i] = 0;
      for (j=0; n-1-j >= 0; ++j) {
        if (++b[n-1-j] < 10)
          break;
        else b[n-1-j]= 0;
      }
      if (b[0] == 0) {
        ++n;
        b[0]= 1;
        for (j = 1; j < n; ++j)
        b[j]=0;
      }
    }
  }
  c[m-1-i] = val;
  a[0] = sign;
  for (i = 0; i < n-1; ++i) {
   if (b[i] > 0)
     break;
   else {
     a[1+i] = sign;
     a[i] = ' ';
   }
  }
  for ( ; i < n; ++i)
    a[1+i] = b[i] + '0';
  a[1+i] = '.';
  for (i = 0; i < m; ++i)
    a[n+2+i] = c[i] + '0';
  return a;
}