2012-04-18 10 views
19

Quiero convertir una matriz de caracteres [] como:matriz de caracteres a un número int en C

char myarray[4] = {'-','1','2','3'}; //where the - means it is negative 

lo tanto, debe ser el número entero: -1234 usando estándar libaries en C. No pude encontrar una forma elegante de hacerlo.

Puedo agregar '\ 0' con seguridad.

+2

1. te falta '4' 2. ¿tienes un terminador nulo para la matriz? – MByD

+2

¿Existe la posibilidad de agregar un '' \ 0'' adicional al final de la matriz? Entonces estaríamos listos en poco tiempo. –

+8

Eso es porque no hay ninguno. Sin embargo, hay formas para cadenas terminadas en nulos. 'atoi' y' strtol' son dos opciones. 'char myarray [] = {'-', '1', '2', '3', '4', 0}; int i = atoi (myarray); ' – falstro

Respuesta

50

Personalmente no me gusta la función atoi. Yo sugeriría sscanf:

char myarray[5] = {'-', '1', '2', '3', '\0'}; 
int i; 
sscanf(myarray, "%d", &i); 

Es muy estándar, que es en el stdio.h biblioteca :)

Y en mi opinión, lo que permite mucha más libertad que atoi, formato arbitrario de su número de cuerdas, y probablemente también permita caracteres no numéricos al final.

EDITAR Acabo de encontrar esta maravillosa question aquí en el sitio que explica y compara 3 maneras 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 funciones *scanf).

Edit2 parece que es no sólo yo personalmente no gusta la función de atoi. Aquí hay un link a una respuesta que explica que la función atoi está en desuso y no debe usarse en el código más reciente.

+4

degustibus ... sscanf agrega una sobrecarga completa en una tarea trivial (argumentos de la lista de variables, formato de cadena de análisis), y en mi humilde opinión es más "propenso a errores". Para tareas simples, prefiero usar funciones simples (atoi está ahí por este motivo) – BigMike

+0

@BigMike Cuando era muy pequeño y comenzaba con 'C', alguien me explicó por qué no era preferible usar' atoi'. Desde entonces, olvidé las razones, pero nunca me gustó usar mucho ... Ahora las estoy buscando y me estoy acordando de ellas. Edité en un enlace una pregunta referente al problema 'atoi', así como una comparación con otras formas de convertir una cadena a int. – penelope

+2

la única razón para desaprobar atoi está relacionada con la seguridad de subprocesos, strtol aún es preferible sobre sscanf para tareas triviales. el punto no es usar atoi o int foo (char *) es usar una función trivial contra una función compleja. el resto es solo una cuestión de gusto.sscanf seguro hace su trabajo, simplemente se desperdicia en tareas tan triviales. Cuando aprendí programación, perdonar que 4/5 ciclos de reloj eran obligatorios. Si más personas siguieran con eso, ahora la aplicación funcionaría a la velocidad de la luz. – BigMike

6

¿Por qué no usar 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 termine con un nulo. Doh!

+6

no es exactamente una buena opción. Funciona por pura pura suerte. la matriz no tiene terminación nula, por lo que los resultados impredecibles pueden venir de atoi – BigMike

+0

Sí. Me di cuenta de eso. ;-) –

+0

¡Gracias! Me faltaba el '\ 0'. Estoy usando una matriz dinámica, así que solo agregué una posición extra. – SpcCode

1

Por lo tanto, la idea es convertir los números de los caracteres (en comillas simples, por ejemplo, '8') en una expresión entera. Por ejemplo, char c = '8'; int i = c - '0' // daría el entero 8; Y sume todos los números convertidos por el principio de que 908 = 9 * 100 + 0 * 10 + 8, que se realiza en un bucle.

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 
+0

ja, pensé que sería autodescriptivo. – ottoshmidt

+0

Si se molesta en agregar el ''\ 0'', sería mejor usar la biblioteca estándar (ver otras respuestas). Este enfoque sería útil, si no pudiera tener el byte NUL de terminación (con la condición de bucle modificada). – hyde

+0

Sí, se me ocurrió una sin usar la biblioteca. – ottoshmidt

1

No es tan difícil manejar la matriz de caracteres sin convertir la matriz en una cadena. Especialmente en el caso en que la longitud de la matriz de caracteres se conoce o se puede encontrar fácilmente. Con el arreglo de caracteres, la longitud debe ser determinado en el mismo alcance que la definición de matriz, por ejemplo .:

size_t len sizeof myarray/sizeof *myarray; 

Para las cadenas que, por supuesto, tiene strlen disponible.

Con la longitud conocida, independientemente de si se trata de una matriz de caracteres o una cadena, puede convertir los valores de caracteres a un número con una función corta similar al 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; 
} 

Por encima es simplemente el enfoque de conversión estándar de char a int con algunos condicionales adicionales incluidos. Para manejar caracteres extraviados, además de digits y '-', el único truco es tomar decisiones inteligentes sobre cuándo comenzar a recopilar dígitos y cuándo detenerse.

Si se inicia la recogida de digits para la conversión cuando se encuentra con el primer digit, a continuación, la conversión termina cuando se encuentra con el primer '-' o non-digit. Esto hace que la conversión sea mucho más conveniente cuando está interesado en índices tales como (por ejemplo, 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 enfrentan a '-' índices de los archivos delimitados (o similares), que depende de usted para negar el resultado. (por ejemplo, file-0123.txt comparado con donde el primero devolvería -123 mientras que el segundo 123).

Ejemplo de salida

$ ./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 juegos de caracteres, etc., sino que trabaja una abrumadora mayoría de las veces y proporciona flexibilidad de conversión adicional sin el análisis inicial o la conversión a cadena requerida por atoi o strtol, etc.

Cuestiones relacionadas