Convierta la matriz de caracteres en un número int en C

8 minutos de lectura

avatar de usuario
CódigoEsp.

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.

  • 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 y strtol 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

avatar de usuario
penélope

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 atoiformato 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.

  • degustibus… sscanf agrega una sobrecarga completa sobre una tarea trivial (argumentos de lista de variables, análisis de cadena de formato), 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

    18 de abril de 2012 a las 7:17

  • @BigMike Cuando era muy pequeño y recién comenzaba Calguien me explicó por qué usar atoi no es preferible Desde entonces, olvidé los motivos, pero nunca me gustó mucho usarlo… Ahora los estoy buscando y me están recordando. Edité en un enlace a una pregunta que se refiere a la atoi problema, así como uno que lo compara con otras formas de convertir una cadena a int.

    – Penélope

    18 de abril de 2012 a las 7:25

  • la única razón para desaprobar atoi está relacionada con cosas seguras para subprocesos, strtol sigue siendo preferible a 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 cuestión de gustos. sscanf seguro hace su trabajo, simplemente se desperdicia en tareas tan triviales. Cuando aprendí a programar, ahorrar esos 4/5 ciclos de reloj era imprescindible. Si más personas siguieran con eso, ahora la aplicación se ejecutaría a la velocidad de la luz.

    – BigMike

    18 de abril de 2012 a las 7:30


  • Y Cómo crees que sscanf obtiene su %d analizado? llama atoiasí que de todos modos eso es bazuca para una hormiga…

    – Eregrith

    18 de abril de 2012 a las 8:00


  • @BigMike: La razón para desaprobar atoi es que falla silenciosamente. Sin embargo, no hay un búfer estático que pueda causar problemas de seguridad de subprocesos. strtol es de hecho la función correcta para usar aquí.

    – Ben Voigt

    06/07/2014 a las 19:55

¿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 exactamente una buena elección. Funciona por pura suerte. la matriz no tiene una terminación nula, por lo que un resultado impredecible puede provenir de atoi

    – BigMike

    18 de abril de 2012 a las 7:08

  • Si. Me acabo de dar cuenta de eso. 😉

    – Rich Drummond

    18 de abril de 2012 a las 7:08

  • ¡Gracias! Me faltaba el ‘\0’. Estoy usando una matriz dinámica, así que acabo de agregar una posición adicional.

    – Código Esp.

    18 de abril de 2012 a las 7:25

avatar de usuario
David C Rankin

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 digitentonces 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 strtoletc

avatar de usuario
Otar Magaldadze

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));

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad