Verificar el flujo de entrada cin produce un número entero

Resuelto user2766546 asked hace 11 años • 8 respuestas

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;

}
user2766546 avatar Sep 11 '13 04:09 user2766546
Aceptado

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;
}
Chemistpp avatar Sep 10 '2013 21:09 Chemistpp

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 optionaltipo 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 inty double, verifique intprimero, ya que cualquier cosa que se convierta en an inttambién es un double.

Dúthomhas avatar Dec 26 '2017 21:12 Dúthomhas

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í

nook avatar Sep 10 '2013 21:09 nook

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 intcorrectamente el tipo correcto (en este caso).

Para obtener más información: http://augustcouncil.com/~tgibson/tutorial/iotips.html#directly

Zac Howland avatar Sep 10 '2013 21:09 Zac Howland