Quiero convertir una matriz de caracteres[] me gusta:
char myarray[4] = {'-','1','2','3'}; //where the - means it is negative
Entonces debería ser el número entero: -1234 usando estándar bibliotecas en C. No pude encontrar ninguna forma elegante de hacerlo.
Puedo agregar el ‘\ 0’ con seguridad.
personalmente no me gusta atoi
función. Yo sugeriría sscanf
:
char myarray[5] = {'-', '1', '2', '3', '\0'};
int i;
sscanf(myarray, "%d", &i);
Es muy estándar, está en el stdio.h
Biblioteca 🙂
Y en mi opinión, te permite mucha más libertad que atoi
formato arbitrario de su cadena de números, y probablemente también permita caracteres que no sean números al final.
EDITAR
Acabo de encontrar esta maravillosa pregunta aquí en el sitio que explica y compara 3 formas diferentes de hacerlo: atoi
, sscanf
y strtol
. Además, hay una buena visión más detallada de sscanf
(en realidad, toda la familia de *scanf
funciones).
EDIT2
Parece que no es solo que personalmente no me guste el atoi
función. Aquí hay un enlace a una respuesta que explica que el atoi
La función está en desuso y no debe usarse en el código más nuevo.
¿Por qué no usar simplemente atoi? Por ejemplo:
char myarray[4] = {'-','1','2','3'};
int i = atoi(myarray);
printf("%d\n", i);
Me da, como se esperaba:
-123
Actualización: por qué no: la matriz de caracteres no termina en nulo. ¡Do!
No es tan difícil lidiar con la matriz de caracteres sin convertir la matriz en una cadena. Especialmente en el caso de que la longitud de la matriz de caracteres se conozca o se pueda encontrar fácilmente. Con la matriz de caracteres, la longitud debe determinarse en el mismo ámbito que la definición de la matriz, por ejemplo:
size_t len sizeof myarray/sizeof *myarray;
Para cuerdas, por supuesto, tienes strlen
disponible.
Con la longitud conocida, independientemente de si se trata de una matriz de caracteres o una cadena, puede convertir los valores de los caracteres en un número con una función corta similar a la siguiente:
/* convert character array to integer */
int char2int (char *array, size_t n)
{
int number = 0;
int mult = 1;
n = (int)n < 0 ? -n : n; /* quick absolute value check */
/* for each character in array */
while (n--)
{
/* if not digit or '-', check if number > 0, break or continue */
if ((array[n] < '0' || array[n] > '9') && array[n] != '-') {
if (number)
break;
else
continue;
}
if (array[n] == '-') { /* if '-' if number, negate, break */
if (number) {
number = -number;
break;
}
}
else { /* convert digit to numeric value */
number += (array[n] - '0') * mult;
mult *= 10;
}
}
return number;
}
Lo anterior es simplemente el enfoque estándar de conversión de char a int con algunos condicionales adicionales incluidos. Para manejar personajes extraviados, además de la digits
y '-'
el único truco es tomar decisiones inteligentes sobre cuándo comenzar a recopilar dígitos y cuándo detenerse.
Si empiezas a coleccionar digits
para la conversión cuando te encuentras con el primero digit
entonces la conversión termina cuando encuentras el primero '-'
o non-digit
. Esto hace que la conversión sea mucho más conveniente cuando se está interesado en índices como (p. ej. file_0127.txt
).
Un breve ejemplo de su uso:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int char2int (char *array, size_t n);
int main (void) {
char myarray[4] = {'-','1','2','3'};
char *string = "some-goofy-string-with-123-inside";
char *fname = "file-0123.txt";
size_t mlen = sizeof myarray/sizeof *myarray;
size_t slen = strlen (string);
size_t flen = strlen (fname);
printf ("\n myarray[4] = {'-','1','2','3'};\n\n");
printf (" char2int (myarray, mlen): %d\n\n", char2int (myarray, mlen));
printf (" string = \"some-goofy-string-with-123-inside\";\n\n");
printf (" char2int (string, slen) : %d\n\n", char2int (string, slen));
printf (" fname = \"file-0123.txt\";\n\n");
printf (" char2int (fname, flen) : %d\n\n", char2int (fname, flen));
return 0;
}
Nota: cuando se enfrenta a '-'
índices de archivos delimitados (o similares), depende de usted negar el resultado. (p.ej file-0123.txt
comparado con file_0123.txt
donde volvería el primero -123
mientras que el segundo 123
).
Salida de ejemplo
$ ./bin/atoic_array
myarray[4] = {'-','1','2','3'};
char2int (myarray, mlen): -123
string = "some-goofy-string-with-123-inside";
char2int (string, slen) : -123
fname = "file-0123.txt";
char2int (fname, flen) : -123
Nota: siempre hay casos de esquina, etc. que pueden causar problemas. Esto no pretende ser 100 % a prueba de balas en todos los conjuntos de caracteres, etc., sino que funciona la gran mayoría de las veces y brinda flexibilidad de conversión adicional sin el análisis inicial o la conversión a cadena requeridos por atoi
o strtol
etc
Entonces, la idea es convertir números de caracteres (entre comillas simples, por ejemplo, ‘8’) en una expresión entera. Por ejemplo char c=”8″; int i = c – ‘0’ //daría el número entero 8; Y suma todos los números convertidos según el principio de que 908=9*100+0*10+8, que se hace en un ciclo.
char t[5] = {'-', '9', '0', '8', '\0'}; //Should be terminated properly.
int s = 1;
int i = -1;
int res = 0;
if (c[0] == '-') {
s = -1;
i = 0;
}
while (c[++i] != '\0') { //iterate until the array end
res = res*10 + (c[i] - '0'); //generating the integer according to read parsed numbers.
}
res = res*s; //answer: -908
No es lo que hace la pregunta, pero usé la respuesta de @Rich Drummond para una lectura de matriz de caracteres desde stdin que tiene terminación nula.
char *buff;
size_t buff_size = 100;
int choice;
do{
buff = (char *)malloc(buff_size *sizeof(char));
getline(&buff, &buff_size, stdin);
choice = atoi(buff);
free(buff);
}while((choice<1)&&(choice>9));
1. te falta
4
2. ¿Tiene un terminador nulo para la matriz?– MByD
18 de abril de 2012 a las 7:03
¿Existe la posibilidad de añadir un extra
'\0'
al final de la matriz? Entonces terminaríamos en poco tiempo.– Señor Lister
18 de abril de 2012 a las 7:04
Eso es porque no hay ninguno. Sin embargo, hay formas para cadenas terminadas en nul.
atoi
ystrtol
son dos opciones.char myarray[] = {'-','1','2','3','4',0}; int i = atoi(myarray);
– falstro
18 de abril de 2012 a las 7:04
@roe, entonces probablemente convertirías esa última en una respuesta 🙂
– Eregrith
18 de abril de 2012 a las 7:07
En lugar de añadir explícitamente el
'\0'
déjalo en manos del compilador:char myarray[] = "-1234";
– Jerry Ataúd
18 de abril de 2012 a las 7:11