¿Cómo se convierte un int
(entero) en una cadena? Estoy tratando de hacer una función que convierta los datos de a struct
en una cadena para guardarlos en un archivo.
int
. Si lo se. Es un atajo muy común, pero todavía me molesta.
¿Cómo se convierte un int
(entero) en una cadena? Estoy tratando de hacer una función que convierta los datos de a struct
en una cadena para guardarlos en un archivo.
int
. Si lo se. Es un atajo muy común, pero todavía me molesta.
Respuestas:
EDITAR: Como se señaló en el comentario, itoa()
no es un estándar, ¡así que mejor use el enfoque sprintf () sugerido en la respuesta rival!
Puede usar la itoa()
función para convertir su valor entero en una cadena.
Aquí hay un ejemplo:
int num = 321;
char snum[5];
// convert 123 to string [buf]
itoa(num, snum, 10);
// print our string
printf("%s\n", snum);
Si desea generar su estructura en un archivo, no es necesario convertir ningún valor de antemano. Puede usar la especificación del formato printf para indicar cómo generar sus valores y utilizar cualquiera de los operadores de la familia printf para generar sus datos.
itoa
no es estándar; consulte, por ejemplo, stackoverflow.com/questions/190229/…
itoa()
sufre el mismo potencial de desbordamiento de búfer que gets()
.
Puedes usarlo sprintf
para hacerlo, o tal vez snprintf
si lo tienes:
char str[ENOUGH];
sprintf(str, "%d", 42);
Donde str
se puede calcular el número de caracteres (más el carácter final) en :
(int)((ceil(log10(num))+1)*sizeof(char))
ENOUGH
es suficiente, podemos hacerlomalloc(sizeof(char)*(int)log10(num))
(int)log10(42)
es así 1
.
#define ENOUGH ((CHAR_BIT * sizeof(int) - 1) / 3 + 2)
int length = snprintf(NULL, 0,"%d",42);
Hágalo de esta manera: use para obtener longitud y luego asigne length+1
caracteres para la cadena.
La respuesta corta es:
snprintf( str, size, "%d", x );
Cuanto más largo sea: primero debe averiguar el tamaño suficiente. snprintf
le dice longitud si lo llama con los NULL, 0
primeros parámetros:
snprintf( NULL, 0, "%d", x );
Asigne un carácter más para nulo-terminador.
#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);
Si funciona para cada cadena de formato, por lo que puede convertir flotante o doble a cadena usando "%g"
, puede convertir int a hexadecimal usando "%x"
, y así sucesivamente.
Después de haber examinado varias versiones de itoa para gcc, la versión más flexible que he encontrado que es capaz de manejar conversiones a binario, decimal y hexadecimal, tanto positiva como negativa, es la cuarta versión encontrada en http://www.strudel.org .uk / itoa / . Si bien sprintf
/ snprintf
tienen ventajas, no manejarán números negativos para otra cosa que no sea la conversión decimal. Dado que el enlace anterior está fuera de línea o ya no está activo, he incluido su cuarta versión a continuación:
/**
* 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()
y "esto es considerablemente más rápido que sprintf" puede ser cierto en su compilador pero no siempre se cumple. Un compilador puede analizarlo sprintf(str, "%d", 42);
y optimizarlo para una itoa()
función similar optimizada , ciertamente más rápido que este usuario. código.
sprintf(str, "%d", 42);
como anexar dos caracteres constantes, pero eso es teoría. En la práctica, las personas no realizan constantes de sprint y el itoa anterior está casi tan optimizado como parece. Al menos, podría estar 100% seguro de que no obtendría órdenes de magnitud de degradación de un sprintf genérico. Sería bueno ver cualquier contraejemplo que tenga en mente, con la versión y la configuración del compilador.
Esto es viejo pero aquí hay otra forma.
#include <stdio.h>
#define atoa(x) #x
int main(int argc, char *argv[])
{
char *string = atoa(1234567890);
printf("%s\n", string);
return 0;
}
Si está usando GCC, puede usar la extensión GNU asprintf function.
char* str;
asprintf (&str, "%i", 12313);
free(str);
La conversión de cualquier cosa a una cadena debe 1) asignar la cadena resultante o 2) pasar un char *
destino y un tamaño. Código de muestra a continuación:
Ambos funcionan para todos, int
incluidos INT_MIN
. Proporcionan una salida consistente a diferencia de lo snprintf()
que depende de la configuración regional actual.
Método 1: Devoluciones NULL
en memoria insuficiente.
#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;
}
Método 2: vuelve NULL
si el búfer era demasiado pequeño.
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;
}
[Editar] como solicitud de @Alter Mann
(CHAR_BIT*sizeof(int_type)-1)*10/33+3
es al menos el número máximo char
necesario para codificar algún tipo de entero con signo como una cadena que consta de un signo negativo opcional, dígitos y un carácter nulo.
El número de bits sin signo en un entero con signo no es más que CHAR_BIT*sizeof(int_type)-1
. Una representación en base 10 de un n
número binario de un bit ocupa hasta n*log10(2) + 1
dígitos. 10/33
es un poco más que log10(2)
. +1 para el signo char
y +1 para el carácter nulo. Otras fracciones podrían usarse como 28/93.
Método 3: Si uno quiere vivir al límite y el desbordamiento del búfer no es una preocupación, sigue una solución simple C99 o posterior que maneja todo 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));
}
Salida de muestra
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;
}
Si desea generar su estructura en un archivo, no es necesario convertir ningún valor de antemano. Puede usar la especificación del formato printf para indicar cómo generar sus valores y utilizar cualquiera de los operadores de la familia printf para generar sus datos.
Use la función itoa()
para convertir un entero en una cadena
Por ejemplo:
char msg[30];
int num = 10;
itoa(num,msg,10);
printf
o uno de sus primos debería hacer el truco