Determine si una cadena C es una int válida en C

Necesito comprobar si una cadena C es un número entero válido.

Intenté ambos

int num=atoi(str); 

y

 int res=sscanf(str, "%d", &num); 

Pero enviar la cadena "8 -9 10" en ambas líneas devuelve simplemente 8, sin indicar la invalidez de esta cadena.

¿Alguien puede sugerir una alternativa?

Eche un vistazo a strtol (), le puede informar sobre partes inválidas de la cadena mediante el retorno del puntero.

Y tenga cuidado con el código de ejemplo entusiasta. Consulte la página del manual para obtener información completa sobre el manejo de errores.

Tal vez me llame la atención por no usar strtol o funciones libc similares, pero el razonamiento sobre este problema no es tan difícil:

 #include  // if using C99... for C++ leave this out. #include  bool is_valid_int(const char *str) { // Handle negative numbers. // if (*str == '-') ++str; // Handle empty string or just "-". // if (!*str) return false; // Check for non-digit chars in the rest of the stirng. // while (*str) { if (!isdigit(*str)) return false; else ++str; } return true; } 

[NB: De lo contrario, podría haber hecho isdigit(*str++) lugar de lo else para mantenerlo más corto, pero mi recuerdo es que los estándares dicen que es posible que isdigit sea ​​una macro.]

Supongo que una limitación es que esto no devuelve falso si el número de la cadena no cabe en un entero. Eso puede o no importarle a usted.

Una manera simple de hacer esto de forma robusta sería leer el int y asegurarse de que la representación de cadena sea idéntica a la cadena de entrada, por ejemplo combinando atoi e itoa :

 int is_int(char const* p) { return strcmp(itoa(atoi(p)), p) == 0; } 

Para verificar si la cadena contiene un número válido, puede usar una expresión regular. Por ejemplo, para el uso de enteros:

[- +]? [0-9] +

y un caso general para números en coma flotante:

[+ -]? [0-9] + [.]? [0-9] * ([eE] [- +]? [0-9] +)?

En el caso de C ++ 11, las funciones de expresiones regulares están disponibles en la biblioteca, por ejemplo, “std :: regex_match (…..)” da la coincidencia exacta. El código debería verse así:

 #include  ..... std::string strnumber("-1.234e+01"); float number; if(regex_match(strnumber,std::regex("[+-]?[0-9]+[.]?[0-9]*([eE][-+]?[0-9]+)?")) number=std::stof(strnumber); else std::cout<<"error, string is not a valid number"; 

Perdón por desenterrar el tema, pero en aras de la exhaustividad y porque este hilo es la primera coincidencia al hacer una búsqueda en Google …

Es posible usar algo como:

 ret = sscanf(string, "%d%n", &number, &idx); if (ret == 0 || string[idx] != '\0') /* handle the error */ 

la directiva %n , que parece ser el estándar C de acuerdo con la página man, cuenta el número de caracteres procesados.

[Editar] sscanf no parece proporcionar una manera de detectar desbordamientos, por lo que la familia de funciones de strtoX debe preferirse en mi humilde opinión.