2010-04-25 44 views
15

En el lenguaje C, ¿Cómo convierto sin signo de valor a largo a una cadena (char *) y mantener el código fuente portátil o simplemente volver a compilar para trabajar en otra plataforma (sin ?? reescribir el códigoCómo convertir largo sin signo a cadena

Por ejemplo, si tengo sprintf(buffer, format, value), como determino el tamaño de la memoria intermedia con forma independiente de la plataforma

+3

'sprintf' ...? – kennytm

+0

con sprintf, cómo determinar el tamaño del búfer de manera independiente de la plataforma – Walidix

+0

@Walidix la respuesta es probablemente limits.h: http://en.wikipedia.org/wiki/Limits.h –

Respuesta

19
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); 
+0

¡Maravilloso! Esto es lo que estoy buscando. Gracias – Walidix

+0

Tenga en cuenta que el VLA ('char buf [n + 1];') requiere C99. – kennytm

+1

@KennyTM: 2010. – jfs

1
char buffer [50]; 

unsigned long a = 5; 

int n=sprintf (buffer, "%lu", a); 
0

Intente utilizar sprintf:

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

Editar:

Tenga en cuenta que usted tiene que asignar un búfer de antemano, y no tienen idea de cuánto tiempo los números serán en realidad cuando lo hace. Supongo 32bit long s, que pueden producir números tan grandes como 10 dígitos.

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

0

Durante mucho valor es necesario agregar la información de longitud 'l' y 'u' para entero decimal sin signo,

como referencia de opciones disponibles ver sprintf

#include <stdio.h> 

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

El el enfoque estándar es usar sprintf(buffer, "%lu", value); para escribir un representante de cadena de value a buffer. Sin embargo, el desbordamiento es un problema potencial, ya que sprintf estará feliz (y sin saberlo) escribiendo sobre el final de su búfer.

Esto es en realidad una gran debilidad del sprintf, parcialmente corregido en C++ mediante el uso de flujos en lugar de búferes. La "respuesta" habitual es asignar un búfer muy generoso que probablemente no se desborde, deje que sprintf lo genere, y luego use strlen para determinar la longitud de cadena real producida, calloc un búfer de (ese tamaño + 1) y copie el hilo a ese .

This site analiza 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.

+0

Sí, usaría 'snprintf'. Es estándar, y proporciona soporte para resolverlo por completo. –

+0

Contradicción de tu gravatar, +1 de cordura –

+0

Imprimir un número es un caso en el que no necesita 'snprintf'; puede enlazar fácilmente el tamaño del buffer requerido. (Imprimiendo con'% s' OTOH, eso requiere precaución.) –

4

puede escribir una función que convierta de largo sin signo 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); 
} 

puede hacer referencia a mi blog here que explica la implementación y uso con el ejemplo.

Cuestiones relacionadas