Come si converte un int
(numero intero) in una stringa? Sto cercando di creare una funzione che converta i dati di astruct
in una stringa per salvarli in un file.
int
. Si lo so. È una scorciatoia molto comune, ma mi infastidisce ancora.
Come si converte un int
(numero intero) in una stringa? Sto cercando di creare una funzione che converta i dati di astruct
in una stringa per salvarli in un file.
int
. Si lo so. È una scorciatoia molto comune, ma mi infastidisce ancora.
Risposte:
EDIT: Come sottolineato nel commento, itoa()
non è uno standard, quindi meglio usare l'approccio sprintf () suggerito nella risposta rivale!
È possibile utilizzare la itoa()
funzione per convertire il valore intero in una stringa.
Ecco un esempio:
int num = 321;
char snum[5];
// convert 123 to string [buf]
itoa(num, snum, 10);
// print our string
printf("%s\n", snum);
Se si desidera generare la propria struttura in un file, non è necessario convertire alcun valore in anticipo. Puoi semplicemente utilizzare la specifica del formato printf per indicare come generare i tuoi valori e utilizzare uno degli operatori della famiglia printf per produrre i tuoi dati.
itoa
non è standard - vedi ad esempio stackoverflow.com/questions/190229/…
itoa()
lo stesso potenziale di overflow del buffer di gets()
.
Puoi usarlo sprintf
per farlo, o forse snprintf
se ce l'hai:
char str[ENOUGH];
sprintf(str, "%d", 42);
Dove il numero di caratteri (più il carattere di chiusura) in str
può essere calcolato usando:
(int)((ceil(log10(num))+1)*sizeof(char))
ENOUGH
sia abbastanza, possiamo farlo entromalloc(sizeof(char)*(int)log10(num))
(int)log10(42)
è 1
.
#define ENOUGH ((CHAR_BIT * sizeof(int) - 1) / 3 + 2)
int length = snprintf(NULL, 0,"%d",42);
per ottenere la lunghezza, quindi allocare i length+1
caratteri per la stringa.
La risposta breve è:
snprintf( str, size, "%d", x );
Più è lungo: prima devi scoprire dimensioni sufficienti. snprintf
ti dice la lunghezza se la chiami con NULL, 0
i primi parametri:
snprintf( NULL, 0, "%d", x );
Allocare un carattere in più per null-terminator.
#include <stdio.h>
#include <stdlib.h>
int x = -42;
int length = snprintf( NULL, 0, "%d", x );
char* str = malloc( length + 1 );
snprintf( str, length + 1, "%d", x );
...
free(str);
Se funziona per ogni stringa di formato, quindi puoi convertire float o double in stringa usando "%g"
, puoi convertire int in hex usando "%x"
e così via.
Dopo aver esaminato varie versioni di itoa per gcc, la versione più flessibile che ho trovato in grado di gestire le conversioni in binario, decimale ed esadecimale, sia positiva che negativa è la quarta versione trovata su http://www.strudel.org .uk / itoa / . Sebbene sprintf
/ snprintf
abbiano vantaggi, non gestiranno numeri negativi per qualcosa di diverso dalla conversione decimale. Poiché il link sopra è off-line o non è più attivo, ho incluso la loro quarta versione di seguito:
/**
* C++ version 0.4 char* style "itoa":
* Written by Lukás Chmela
* Released under GPLv3.
*/
char* itoa(int value, char* result, int base) {
// check that the base if valid
if (base < 2 || base > 36) { *result = '\0'; return result; }
char* ptr = result, *ptr1 = result, tmp_char;
int tmp_value;
do {
tmp_value = value;
value /= base;
*ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz" [35 + (tmp_value - value * base)];
} while ( value );
// Apply negative sign
if (tmp_value < 0) *ptr++ = '-';
*ptr-- = '\0';
while(ptr1 < ptr) {
tmp_char = *ptr;
*ptr--= *ptr1;
*ptr1++ = tmp_char;
}
return result;
}
sprintf()
e "questo è considerevolmente più veloce di sprintf" può essere vero sul tuo compilatore ma non sempre vale. Un compilatore può esaminarlo sprintf(str, "%d", 42);
e ottimizzarlo in una itoa()
funzione simile ottimizzata , sicuramente più veloce di questo utente. codice.
sprintf(str, "%d", 42);
come aggiunta di due caratteri costanti, ma questa è teoria. In pratica, le persone non sprintano le costanti e gli itoa sopra sono quasi ottimizzati come si arriva. Almeno potresti essere sicuro al 100% di non ottenere ordini di grandezza declassati di uno sprintf generico. Sarebbe bello vedere qualunque controesempio tu abbia in mente, con la versione e le impostazioni del compilatore.
Questo è vecchio ma ecco un altro modo.
#include <stdio.h>
#define atoa(x) #x
int main(int argc, char *argv[])
{
char *string = atoa(1234567890);
printf("%s\n", string);
return 0;
}
Se stai usando GCC, puoi usare l'estensione GNU come funzione asprintf.
char* str;
asprintf (&str, "%i", 12313);
free(str);
La conversione di qualsiasi cosa in una stringa dovrebbe o 1) allocare la stringa risultante o 2) passare in a char *
destinazione e dimensione. Codice di esempio di seguito:
Entrambi funzionano per tutti int
compresi INT_MIN
. Forniscono un output coerente a differenzasnprintf()
che dipende dalle impostazioni internazionali correnti.
Metodo 1: restituisce NULL
memoria insufficiente.
#define INT_DECIMAL_STRING_SIZE(int_type) ((CHAR_BIT*sizeof(int_type)-1)*10/33+3)
char *int_to_string_alloc(int x) {
int i = x;
char buf[INT_DECIMAL_STRING_SIZE(int)];
char *p = &buf[sizeof buf - 1];
*p = '\0';
if (i >= 0) {
i = -i;
}
do {
p--;
*p = (char) ('0' - i % 10);
i /= 10;
} while (i);
if (x < 0) {
p--;
*p = '-';
}
size_t len = (size_t) (&buf[sizeof buf] - p);
char *s = malloc(len);
if (s) {
memcpy(s, p, len);
}
return s;
}
Metodo 2: restituisce NULL
se il buffer era troppo piccolo.
static char *int_to_string_helper(char *dest, size_t n, int x) {
if (n == 0) {
return NULL;
}
if (x <= -10) {
dest = int_to_string_helper(dest, n - 1, x / 10);
if (dest == NULL) return NULL;
}
*dest = (char) ('0' - x % 10);
return dest + 1;
}
char *int_to_string(char *dest, size_t n, int x) {
char *p = dest;
if (n == 0) {
return NULL;
}
n--;
if (x < 0) {
if (n == 0) return NULL;
n--;
*p++ = '-';
} else {
x = -x;
}
p = int_to_string_helper(p, n, x);
if (p == NULL) return NULL;
*p = 0;
return dest;
}
[Modifica] come richiesto da @Alter Mann
(CHAR_BIT*sizeof(int_type)-1)*10/33+3
è almeno il numero massimo di char
necessario per codificare il tipo intero con segno come una stringa costituita da un segno negativo facoltativo, cifre e un carattere null.
Il numero di bit non di segno in un numero intero con segno non è maggiore di CHAR_BIT*sizeof(int_type)-1
. Una rappresentazione in base 10 di un n
numero binario a bit richiede fino a n*log10(2) + 1
cifre. 10/33
è leggermente più di log10(2)
. +1 per il segno char
e +1 per il carattere null. Altre frazioni potrebbero essere usate come 28/93.
Metodo 3: Se si vuole vivere al limite e il buffer overflow non è un problema, segue una semplice soluzione C99 o successiva che gestisce tutto int
.
#include <limits.h>
#include <stdio.h>
static char *itoa_simple_helper(char *dest, int i) {
if (i <= -10) {
dest = itoa_simple_helper(dest, i/10);
}
*dest++ = '0' - i%10;
return dest;
}
char *itoa_simple(char *dest, int i) {
char *s = dest;
if (i < 0) {
*s++ = '-';
} else {
i = -i;
}
*itoa_simple_helper(s, i) = '\0';
return dest;
}
int main() {
char s[100];
puts(itoa_simple(s, 0));
puts(itoa_simple(s, 1));
puts(itoa_simple(s, -1));
puts(itoa_simple(s, 12345));
puts(itoa_simple(s, INT_MAX-1));
puts(itoa_simple(s, INT_MAX));
puts(itoa_simple(s, INT_MIN+1));
puts(itoa_simple(s, INT_MIN));
}
Uscita campione
0
1
-1
12345
2147483646
2147483647
-2147483647
-2147483648
/*Function return size of string and convert signed *
*integer to ascii value and store them in array of *
*character with NULL at the end of the array */
int itoa(int value,char *ptr)
{
int count=0,temp;
if(ptr==NULL)
return 0;
if(value==0)
{
*ptr='0';
return 1;
}
if(value<0)
{
value*=(-1);
*ptr++='-';
count++;
}
for(temp=value;temp>0;temp/=10,ptr++);
*ptr='\0';
for(temp=value;temp>0;temp/=10)
{
*--ptr=temp%10+'0';
count++;
}
return count;
}
Se si desidera generare la propria struttura in un file, non è necessario convertire alcun valore in anticipo. Puoi semplicemente utilizzare la specifica del formato printf per indicare come generare i tuoi valori e utilizzare uno degli operatori della famiglia printf per produrre i tuoi dati.
Utilizzare la funzione itoa()
per convertire un numero intero in una stringa
Per esempio:
char msg[30];
int num = 10;
itoa(num,msg,10);
printf
o uno dei suoi cugini dovrebbe fare il trucco