Cómo convertir un largo sin firmar a cadena

En el lenguaje C, ¿cómo convierto un valor largo sin firmar en una cadena ( char * ) y mantengo mi código fuente portátil o lo recompilo para que funcione en otra plataforma (sin volver a escribir el código?

Por ejemplo, si tengo sprintf(buffer, format, value) , ¿cómo puedo determinar el tamaño del búfer de manera independiente de la plataforma?

 const int n = snprintf(NULL, 0, "%lu", ulong_value); assert(n > 0); char buf[n+1]; int c = snprintf(buf, n+1, "%lu", ulong_value); assert(buf[n] == '\0'); assert(c == n); 

El enfoque estándar es usar sprintf(buffer, "%lu", value); para escribir una cadena de value al buffer . Sin embargo, el desbordamiento es un problema potencial, ya que sprintf escribirá felizmente (y sin saberlo) sobre el final de tu búfer.

Esta es realmente una gran debilidad de sprintf, parcialmente corregida en C ++ mediante el uso de flujos en lugar de buffers. La “respuesta” habitual es asignar un búfer muy generoso que probablemente no se desbordará, dejar que sprintf produzca eso, y luego usar strlen para determinar la longitud real de la cadena producida, llamar a un búfer (ese tamaño + 1) y copiar la cadena .

Este sitio discute esto y los problemas relacionados en cierta extensión.

Algunas bibliotecas ofrecen snprintf como una alternativa que le permite especificar un tamaño máximo de búfer.

puede escribir una función que se convierta de un largo sin signo a un str, similar a la función de biblioteca ltostr.

 char *ultostr(unsigned long value, char *ptr, int base) { unsigned long t = 0, res = 0; unsigned long tmp = value; int count = 0; if (NULL == ptr) { return NULL; } if (tmp == 0) { count++; } while(tmp > 0) { tmp = tmp/base; count++; } ptr += count; *ptr = '\0'; do { res = value - base * (t = value / base); if (res < 10) { * -- ptr = '0' + res; } else if ((res >= 10) && (res < 16)) { * --ptr = 'A' - 10 + res; } } while ((value = t) != 0); return(ptr); } 

Puede consultar mi blog aquí, que explica la implementación y el uso con ejemplos.

 char buffer [50]; unsigned long a = 5; int n=sprintf (buffer, "%lu", a); 

Intenta usar sprintf :

 unsigned long x=1000000; char buffer[21]; sprintf(buffer,"%lu", x); 

Editar:

Observe que tiene que asignar un búfer por adelantado y no tiene idea de cuánto durarán realmente los números cuando lo haga. Asumo que 32bit long s, que puede producir números de hasta 10 dígitos.

Vea la respuesta de Carl Smotricz para una mejor explicación de los problemas involucrados.

Para un valor largo, debe agregar la información de longitud ‘l’ y ‘u’ para un entero decimal sin signo,

Como referencia de opciones disponibles ver sprintf.

 #include  int main () { unsigned long lval = 123; char buffer [50]; sprintf (buffer, "%lu" , lval ); }