
Walidix
En el lenguaje C, ¿cómo convierto largo sin firmar valor a una cadena (carácter *) y mantener mi código fuente portátil o simplemente volver a compilarlo para que funcione en otra plataforma (¿sin reescribir el código?
Por ejemplo, si tengo sprintf(buffer, format, value)
¿cómo determino el tamaño del búfer con una plataforma independiente?

jfs
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);

carl smotricz
El enfoque estándar es utilizar sprintf(buffer, "%lu", value);
para escribir un representante de cadena de value
para buffer
. Sin embargo, el desbordamiento es un problema potencial, ya que sprintf
felizmente (y sin saberlo) escribirá sobre el final de su búfer.
En realidad, esta es una gran debilidad de sprintf, parcialmente corregida en C++ mediante el uso de secuencias en lugar de búferes. La “respuesta” habitual es asignar un búfer muy generoso que es poco probable que se desborde, dejar que sprintf genere ese resultado y luego usar strlen para determinar la longitud real de la cadena producida, llamar a un búfer de (ese tamaño + 1) y copiar la cadena en ese .
Este sitio discute este y otros problemas relacionados con cierta extensión.
Algunas bibliotecas ofrecen snprintf
como una alternativa que le permite especificar un tamaño de búfer máximo.

usuario2083050
puede escribir una función que convierta de unsigned long a 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);
}
puedes consultar mi blog aquí que explica la implementación y el uso con un ejemplo.
char buffer [50];
unsigned long a = 5;
int n=sprintf (buffer, "%lu", a);

hacer
Intenta usar sprintf
:
unsigned long x=1000000;
char buffer[21];
sprintf(buffer,"%lu", x);
Editar:
Tenga en cuenta que debe asignar un búfer por adelantado y no tiene idea de cuánto tiempo serán realmente los números cuando lo haga. asumo 32 bits long
s, que puede producir números de hasta 10 dígitos.
Consulte la respuesta de Carl Smotricz para obtener una mejor explicación de los problemas involucrados.

apilador
Para un valor largo, debe agregar la información de longitud ‘l’ y ‘u’ para un entero decimal sin signo,
como referencia de las opciones disponibles ver correr
#include <stdio.h>
int main ()
{
unsigned long lval = 123;
char buffer [50];
sprintf (buffer, "%lu" , lval );
}
con sprintf, cómo determinar el tamaño del búfer de manera independiente de la plataforma
– Walidix
25 de abril de 2010 a las 20:01
@Walidix la respuesta probablemente sea limites.h : en.wikipedia.org/wiki/Limits.h
– Andréi Ciobanu
25 de abril de 2010 a las 20:03
En realidad, esta es una gran debilidad de sprintf, parcialmente corregida en C++ mediante el uso de secuencias en lugar de búferes. La “respuesta” habitual es asignar un búfer muy generoso que probablemente no se desborde, dejar que sprintf genere eso y luego usar
strlen
para determinar la longitud real de la cadena producida,calloc
un búfer de (ese tamaño + 1) y copie la cadena en eso.-Carl Smotricz
25 de abril de 2010 a las 20:05
@Walidix: necesitas calcular
log10(ULONG_MAX)
…– kennytm
25 de abril de 2010 a las 20:09
Una respuesta infalible es
snprintf
si lo tienes. Ver mi respuesta para un poco más de detalle.-Carl Smotricz
25 de abril de 2010 a las 20:09