c - reales - propiedades de los numeros enteros
¿Cómo verificar para asegurarse de tener un número entero antes de llamar a atoi()? (8)
Deseo tomar un número entero como un argumento de línea de comando, pero si el usuario pasa una cadena no entera, esto causará un desbordamiento de la pila. ¿Cuál es la forma estándar de garantizar que atoi () tenga éxito?
¿Causa un desbordamiento de pila? Bueno, supongo que ese es un posible resultado del comportamiento indefinido si el valor en la cadena sobrepasa el rango de int
. En la práctica, por lo general solo se envuelve o devuelve un resultado falso.
Si desea una mejor comprobación de errores, use strtol
lugar de atoi
. Tiene un comportamiento bien definido en overflow (establece errno
, que necesita borrar a 0 antes de llamar a strtol
para que pueda distinguir entre devoluciones de errores y devolver valores legítimos) y puede examinar el punto en la cadena en la que detuvo la conversión para ver si la cadena completa era un número entero o si hay contenido adicional más allá del final.
Esto no causa desbordamiento de pila. atoi
devuelve 0
si no puede encontrar un número al comienzo de la cadena. Su (no) manejo del 0
es lo que causa el desbordamiento de la pila.
Esto podría ayudarte. Ver strtol disponible en stdlib.h
No creo que un atoi estándar pueda acumularse, pero no hay manera de saber si no tiene un número entero. Use strtol
lugar - es posible tratar con números enteros.
O bien puede hacer esto y entrar en un terreno de Comportamiento no definido, puede escribir una función de validación simple como esta:
/* returns 0 on success, 1 on failure. */
int verify(char * string)
{
int x = 0;
int len = strlen(string);
while(x < len) {
if(!isdigit(*(string+x)))
return 1;
++x;
}
return 0;
}
Tenga en cuenta que debe llamar a esta función antes de llamar a atoi (), y necesita string.h y stdio.h.
Puedes usar:
long int strtol(const char *nptr, char **endptr, int base);
Luego, compruebe si *endptr != nptr
. Esto significa que la cadena al menos comienza con el número entero. También puede verificar que * endptr apunta a cero de terminación, lo que significa que la cadena completa fue analizada con éxito.
atoi()
causará (debería) un desbordamiento de pila si la cadena contiene caracteres que no sean dígitos. Simplemente convertirá a int
cualquier dígito que encuentre desde el comienzo de la cadena hasta que no haya más.
int x = atoi("12monkeys"); // x is 12
int y = atoi("monkeys12"); // y is 0
Puede verificar que no haya un desbordamiento de enteros (número fuera del rango de [-2 ^ 31, 2 ^ 31-1] en una arquitectura de PC moderna (actual)).
editar (comentarios)
Mientras que las normas C advierten sobre un comportamiento indefinido si el valor no se puede representar, los compiladores recientes más comunes de C (gcc, MS ...) no se bloquean si el valor no es aceptable (a menos que el puntero char *
sea nulo o incorrecto de curso).
De todos modos, puedes implementar tu propio atoi()
fácilmente (con las mismas limitaciones que en mi respuesta)
#include <ctype.h>
int myatoi(char *s) {
int res = 0, minus = *s == ''-'';
if (minus) s++;
while (isdigit(*s)) {
res = res*10 + (*s++ - ''0'');
}
return minus ? -res : res;
}
atoi()
está convirtiendo la cadena en un entero si contiene solo caracteres de dígitos, de lo contrario devolverá 0.