saber - validar que solo ingrese numeros en c++
¿Cómo puedo saber si la función c atoi falló o si fue una cadena de ceros? (6)
Para C ++ 11 y posterior:
La función ir para la conversión de cadena a entero ahora es stoi
, que toma una string
y devuelve un int
, o arroja una excepción en caso de error.
Ya no es necesario el hack detallado de istringstream
mencionado en la respuesta aceptada.
(También hay stol
/ stoll
/ stof
/ stod
/ stold
para conversiones long double
long
/ long long
/ float
/ double
/ long double
, respectivamente.)
Cuando se usa la función atoi
(o strtol
o funciones similares para el caso), ¿cómo se puede saber si la conversión entera falló o si la cadena C que se estaba convirtiendo era un 0
?
Por lo que estoy haciendo, 0
es un valor aceptable y la cadena C que se está convirtiendo puede contener cualquier cantidad de 0
s. También puede tener espacios en blanco principales.
Como esto está etiquetado c ++ :
template< typename T >
inline T convert(const std::string& str)
{
std::istringstream iss(str);
T obj;
iss >> std::ws >> obj >> std::ws;
if(!iss.eof())
throw "dammit!";
return obj;
}
Desde la página man para strtol ():
Si endptr no es NULL, strtol () almacena la dirección del primer carácter no válido en * endptr. Sin embargo, si no había ningún dígito, strtol () almacena el valor original de nptr en * endptr. (Por lo tanto, si * nptr no es
''/0''
sino ** endptr es''/0''
a la vuelta, toda la cadena era válida.)
Ha pasado un tiempo desde que lo hice y C / C ++, pero me parece que la solución (demasiado) simple sería verificar solo la cadena para "0".
int value = atoi(string_number.c_str());
if ( !value && string_number != "0" ) {
// error
} else {
// great success!
}
La función adecuada (siempre que insista en usar funciones de estilo C) es strtol
y el código de conversión puede verse de la siguiente manera
const char *number = "10"; /* for example */
char *end;
long value = strtol(number, &end, 10);
if (end == number || *end != ''/0'' || errno == ERANGE)
/* ERROR, abort */;
/* Success */
/* Add whatever range checks you want to have on the value of `value` */
Algunas observaciones:
strtol
permite (es decir, omite silenciosamente) espacios en blanco delante del número real. Si tiene que tratar estos espacios en blanco como un error, debe verificarlo usted mismo.
La comprobación de *end != ''/0''
asegura que no haya nada después de los dígitos. Si desea permitir otros caracteres después del número real (espacio en blanco?), Esta verificación debe modificarse en consecuencia.
PD: agregué el end == number
verificación más tarde para capturar las secuencias de entrada vacías. Las entradas "All whitespace" y "no number all" han sido capturadas por *end != ''/0''
check alone. Sin embargo, podría tener sentido capturar entradas vacías de antemano. En ese caso, la verificación del end == number
será / podría ser innecesaria.
Una alternativa a strtol
es sscanf
, aunque es un poco pesado:
const char *numStr = "12345"; // input string
int value;
if(sscanf(numStr, "%d", &value) == 1)
; // parsing succeeded, use value
else
; // error
Sin embargo, esto permite espacios en blanco en su cadena (que puede o no ser deseable), y permite que cualquier cosa siga el número, por lo que se aceptará "123abc" y devolverá 123. Si desea tener un control más estricto, vaya con strtol()
, como demuestra AndreyT .