HOWTO · C

Cómo convertir una cadena en un número entero en C

Este artículo presenta diferentes métodos en C para convertir una cadena en un entero

En esta página

Convertir una cadena de C en un entero depende de qué entradas acepte el programa y de las comprobaciones que necesite. La biblioteca estándar ofrece atoi(), strtol() y strtoumax(). Usa atoi() solo cuando la entrada sea confiable; si puede estar mal formada o quedar fuera del rango del tipo de destino, prefiere una conversión comprobada con strtol() o strtoumax().

Usar atoi() para convertir una cadena en un entero en C

atoi(), de <stdlib.h>, omite los espacios en blanco iniciales, lee un signo opcional y los dígitos decimales, y se detiene ante el primer carácter que no forma parte del número. Devuelve un int, pero su interfaz no indica dónde terminó el análisis ni permite distinguir entre un cero válido y una conversión fallida. Si el valor convertido no se puede representar como int, el comportamiento no está definido. Úsala solo cuando otros medios garanticen el formato y el rango de la entrada.

Ejecuta este ejemplo:

El código y las etiquetas o salidas visibles de esta sección se mantienen en inglés.

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    const char *input = "123";
    int value = atoi(input);
    printf("%s -> %d\n", input, value);
    return 0;
}

Salida observada:

123 -> 123

Usar strtol() para convertir una cadena en un entero en C

strtol(), declarado en <stdlib.h>, devuelve un long. Acepta una base de 2 a 36: la base 10 lee valores decimales y la base 0 reconoce los prefijos habituales de los enteros de C. Omite los espacios en blanco iniciales y se detiene ante el primer carácter que no pertenece al número. Pasa la dirección de un puntero de fin para localizar esa posición. Si el puntero de fin aún apunta al primer carácter de la entrada, no se convirtió ningún dígito; si después de la conversión apunta a un carácter distinto de nulo, la entrada tiene un sufijo.

Establece errno en cero antes de llamar a strtol(). Si el resultado es LONG_MIN o LONG_MAX y errno == ERANGE, el valor estaba fuera del rango de long. Si el tipo de destino es int, comprueba también que el valor esté entre INT_MIN e INT_MAX antes de convertirlo. Este ejemplo completo acepta únicamente un valor decimal entero que quepa en un int:

El código y las etiquetas o salidas visibles de esta sección se mantienen en inglés.

#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>

int main(void) {
    const char *input = "123";
    char *end;
    errno = 0;
    long parsed = strtol(input, &end, 10);

    if (end == input || *end != '\0' || errno == ERANGE ||
        parsed < INT_MIN || parsed > INT_MAX) {
        puts("conversion failed");
        return 0;
    }

    printf("value=%d\n", (int)parsed);
    return 0;
}

Salida observada:

value=123

En código de producción, decide si se deben aceptar espacios en blanco alrededor del valor o un sufijo. strtol() permite los espacios iniciales, mientras que la comprobación del puntero de fin de este ejemplo rechaza cualquier sufijo después de los dígitos.

Usar strtoumax() para convertir una cadena en un entero en C

strtoumax(), declarado en <inttypes.h>, convierte la entrada a uintmax_t, el tipo entero sin signo más amplio que ofrece la implementación. Al igual que strtol(), recibe un puntero de fin y una base, e indica un desbordamiento de rango mediante errno == ERANGE después de haber puesto errno a cero. Incluye <stdint.h> para el tipo uintmax_t y <inttypes.h> para la función y la macro de formato PRIuMAX.

Una conversión sin signo puede aceptar un signo menos inicial y producir un resultado sin signo conforme a las reglas de la función. Si la aplicación exige una entrada no negativa, rechaza explícitamente el signo menos. El ejemplo siguiente también exige al menos un dígito, rechaza los caracteres finales y muestra el valor con la macro de formato correspondiente:

El código y las etiquetas o salidas visibles de esta sección se mantienen en inglés.

#include <ctype.h>
#include <errno.h>
#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

int main(void) {
    const char *input = "123";
    const char *sign = input;
    while (isspace((unsigned char)*sign)) {
        ++sign;
    }

    if (*sign == '-') {
        puts("conversion failed");
        return 0;
    }

    char *end;
    errno = 0;
    uintmax_t value = strtoumax(input, &end, 10);
    if (end == input || *end != '\0' || errno == ERANGE) {
        puts("conversion failed");
        return 0;
    }

    printf("value=%" PRIuMAX "\n", value);
    return 0;
}

Salida observada:

value=123

El tipo del resultado no tiene signo y puede ser más amplio que int; antes de convertirlo a un tipo más estrecho, comprueba el valor frente al máximo de ese tipo de destino.

Elegir una función de C para convertir cadenas en enteros

Elige atoi() cuando la entrada sea confiable, quepa en un int y el programa no necesite distinguir entre una entrada mal formada y el valor cero. Para entradas del usuario, archivos u otros datos que quizá no sigan el formato esperado, strtol() suele ser la mejor opción para una conversión con signo, porque su puntero de fin y errno permiten validar el resultado. Comprueba tanto el rango de long como el de cualquier tipo de destino más estrecho.

Elige strtoumax() para una cantidad no negativa que pueda superar el rango positivo de long. Comprueba que se hayan procesado dígitos, rechaza el texto final si toda la cadena debe ser numérica, verifica ERANGE y aplica cualquier límite más estrecho propio de la aplicación. Ninguna de las dos funciones con comprobaciones determina qué considera aceptable tu aplicación: quien llama debe decidir si permite espacios en blanco, signos, prefijos o caracteres finales y verificar esas reglas antes de usar el resultado.