Verificar el flujo de entrada cin produce un número entero
Estaba escribiendo esto y le pide al usuario que ingrese dos números enteros que luego se convertirán en variables. Desde allí realizará operaciones sencillas.
¿Cómo hago para que la computadora verifique si lo ingresado es un número entero o no? Y si no, pídale al usuario que escriba un número entero. Por ejemplo: si alguien ingresa "a" en lugar de 2, le indicará que vuelva a ingresar un número.
Gracias
#include <iostream>
using namespace std;
int main ()
{
int firstvariable;
int secondvariable;
float float1;
float float2;
cout << "Please enter two integers and then press Enter:" << endl;
cin >> firstvariable;
cin >> secondvariable;
cout << "Time for some simple mathematical operations:\n" << endl;
cout << "The sum:\n " << firstvariable << "+" << secondvariable
<<"="<< firstvariable + secondvariable << "\n " << endl;
}
Puedes comprobarlo así:
int x;
cin >> x;
if (cin.fail()) {
//Not an int.
}
Además, puede continuar recibiendo información hasta que obtenga un int a través de:
#include <iostream>
int main() {
int x;
std::cin >> x;
while(std::cin.fail()) {
std::cout << "Error" << std::endl;
std::cin.clear();
std::cin.ignore(256,'\n');
std::cin >> x;
}
std::cout << x << std::endl;
return 0;
}
EDITAR: Para abordar el comentario a continuación sobre entradas como 10abc, se podría modificar el bucle para aceptar una cadena como entrada. Luego verifique la cadena en busca de algún carácter que no sea un número y maneje esa situación en consecuencia. No es necesario borrar/ignorar el flujo de entrada en esa situación. Verificando que la cadena sea solo números, convierta la cadena nuevamente a un número entero. Quiero decir, esto fue simplemente improvisado. Puede que haya una mejor manera. Esto no funcionará si acepta flotantes/dobles (tendría que agregar '.' en la cadena de búsqueda).
#include <iostream>
#include <string>
int main() {
std::string theInput;
int inputAsInt;
std::getline(std::cin, theInput);
while(std::cin.fail() || std::cin.eof() || theInput.find_first_not_of("0123456789") != std::string::npos) {
std::cout << "Error" << std::endl;
if( theInput.find_first_not_of("0123456789") == std::string::npos) {
std::cin.clear();
std::cin.ignore(256,'\n');
}
std::getline(std::cin, theInput);
}
std::string::size_type st;
inputAsInt = std::stoi(theInput,&st);
std::cout << inputAsInt << std::endl;
return 0;
}
Je, esta es una vieja pregunta que podría necesitar una mejor respuesta.
La entrada del usuario debe obtenerse como una cadena y luego intentar convertirse al tipo de datos que desee. Convenientemente, esto también le permite responder preguntas como "¿qué tipo de datos son mis datos de entrada?"
Aquí hay una función que uso mucho. Existen otras opciones, como en Boost, pero la premisa básica es la misma: intente realizar la conversión de cadena→tipo y observe el éxito o el fracaso:
template <typename T>
auto string_to( const std::string & s )
{
T value;
std::istringstream ss( s );
return ((ss >> value) and (ss >> std::ws).eof()) // attempt the conversion
? value // success
: std::optional<T> { }; // failure
}
Usar el optional
tipo es solo una forma. También puede generar una excepción o devolver un valor predeterminado en caso de falla. Lo que sea que funcione para su situación.
A continuación se muestra un ejemplo de su uso:
int n;
std::cout << "n? ";
{
std::string s;
getline( std::cin, s );
auto x = string_to <int> ( s );
if (!x) return complain();
n = *x;
}
std::cout << "Multiply that by seven to get " << (7 * n) << ".\n";
limitaciones e identificación del tipo
Para que esto funcione, por supuesto, debe existir un método para extraer sin ambigüedades su tipo de datos de una secuencia. Este es el orden natural de las cosas en C++, es decir, seguir como siempre. Entonces no hay sorpresas aquí.
La siguiente advertencia es que algunos tipos subsumen a otros. Por ejemplo, si está intentando distinguir entre int
y double
, verifique int
primero, ya que cualquier cosa que se convierta en an int
también es un double
.
Hay una función en c llamada isdigit()
. Eso te vendrá muy bien. Ejemplo:
int var1 = 'h';
int var2 = '2';
if( isdigit(var1) )
{
printf("var1 = |%c| is a digit\n", var1 );
}
else
{
printf("var1 = |%c| is not a digit\n", var1 );
}
if( isdigit(var2) )
{
printf("var2 = |%c| is a digit\n", var2 );
}
else
{
printf("var2 = |%c| is not a digit\n", var2 );
}
De aquí
Si istream no se inserta, establecerá el bit de error.
int i = 0;
std::cin >> i; // type a and press enter
if (std::cin.fail())
{
std::cout << "I failed, try again ..." << std::endl
std::cin.clear(); // reset the failed state
}
Puede configurar esto en un bucle do- while para insertar int
correctamente el tipo correcto (en este caso).
Para obtener más información: http://augustcouncil.com/~tgibson/tutorial/iotips.html#directly