2010-04-25 14 views
15

Nel linguaggio C, come faccio a convertire unsigned valore a lungo in una stringa (char *) e mantenere il mio codice sorgente portatile o semplicemente ricompilare a lavorare su altre piattaforme (senza ?? riscrivere il codiceCome convertire unsigned long in stringa

Per esempio, se ho sprintf(buffer, format, value), come faccio a determinare la dimensione del buffer con maniera indipendente dalla piattaforma

+3

'sprintf' ...? – kennytm

+0

con sprintf, come determinare la dimensione del buffer in modo indipendente dalla piattaforma – Walidix

+0

@Walidix la risposta è probabilmente limits.h: http://en.wikipedia.org/wiki/Limits.h –

risposta

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

Meraviglioso !!! Questo è quello che sto cercando. Grazie – Walidix

+0

Nota il VLA ('char buf [n + 1];') richiede C99. – kennytm

+1

@KennyTM: 2010. – jfs

1
char buffer [50]; 

unsigned long a = 5; 

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

Prova utilizzando sprintf:

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

Edit:

Si noti che è necessario allocare un buffer in anticipo, e non hanno idea di quanto tempo i numeri saranno effettivamente quando si fa così. Sto assumendo 32 bit long s, che può produrre numeri fino a 10 cifre.

Vedere la risposta di Carl Smotricz per una migliore spiegazione dei problemi coinvolti.

0

Per molto valore è necessario aggiungere le informazioni di lunghezza 'L' e 'u' per intero senza segno decimale,

come riferimento di opzioni disponibili vedi sprintf

#include <stdio.h> 

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

Il L'approccio standard prevede l'uso di sprintf(buffer, "%lu", value); per scrivere una ripetizione di stringa da value a buffer. Tuttavia, l'overflow è un potenziale problema, dato che sprintf scriverà felicemente (e inconsapevolmente) alla fine del buffer.

Questo è in realtà un grande punto debole di sprintf, parzialmente risolto in C++ utilizzando flussi anziché buffer. La solita "risposta" è quella di allocare un buffer molto generoso che non rischia di traboccare, lasciare sprintf a quello, e quindi usare strlen per determinare la lunghezza effettiva della stringa prodotta, chiamare un buffer di (quella dimensione + 1) e copiare la stringa in quel .

This site discute questo e alcuni problemi correlati.

Alcune librerie offrono snprintf un'alternativa che consente di specificare una dimensione massima del buffer.

+0

Sì, userei 'snprintf'. È standard, e fornisce il supporto per risolvere completamente questo. –

+0

Contraddice al tuo gravatar, +1 per sanità mentale –

+0

La stampa di un numero è un caso in cui non è necessario 'snprintf', si può facilmente limitare la dimensione del buffer richiesta. (Stampa con'% s' OTOH, che richiede cautela.) –

4

è possibile scrivere una funzione che converte da unsigned long a str, simile alla funzione di libreria 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); 
} 

è possibile fare riferimento al mio blog here che spiega l'attuazione e l'utilizzo con l'esempio.

Problemi correlati