Estaba aprendiendo un poco de C++ cuando decidí armar un programa que creara gráficos de tortuga. Al empezar a desarrollarlo arme un menú para acceder a las opciones de manera numérica y me tropecé con el problema de validar que el dato introducido fuera de tipo numérico.
Indagando un poco por Internet lo primero que me encontré fue una función para validar la introducción de dígitos: isdigit de la librería ctype.h ó cctype. El problema con dicha función es que, aunque valida el tipo, solo lo hace en caso de ser un dígito, pero no en el caso de ser un número con más de 1 solo dígito.
Leyendo un poco, encontré que tal vez el problema se podía resolver utilizando aritmética binaria y manejo de bits de error de la librería iostream. Encontré este tutorial: Controles de flujo (Parte 2). El tutorial me pareció muy adecuado, pero al probarlo note que era necesario realizar dos Enter para que funcionara de manera adecuada.
El problema del Enter surge por la instrucción:
Código :
cin.ignore(1024, '\n');Aparte de dicho problema, esta instrucción y está comparación me parecieron un poco alocadas para este problema:
Código :
estado = cin.rdstate(); if ((estado & ios::failbit) == ios::failbit)Me pareció que la mejor manera de solucionarlo era a partir del funcionamiento de los flujos en c++.
Decidí por mi cuenta investigar un poco más y encontré el manejo de estado de error de flujo. Obteniendo como resultado el siguiente código:
Validar datos entrados por el usuario en C++
Código :
/* Validación de tipos de datos sin usar aritmética binaria en c++ Autor: John Sánchez Alvarez Este código es libre de usar y modificarse*/ #include <iostream> using namespace std; int main (){ int numero, cont = 0; bool continuar; do { continuar = false; cin.clear(); if(cont > 0) cin.ignore(1024, '\n'); cout << "Introduce un numero: "; cin >> numero; cont++; if(cin.fail() && cin.rdstate()){ cout << "NO ES UN NUMERO" << endl; continuar = true; } } while (continuar); }Lo intentaré explicar lo más detalladamente posible.
Para poder hacer la comprobación efectivamente es necesario el uso de la librería iostream. El estado de flujo se puede comprobar por medio de los bits de la clase ios. La cual es la clase base de istream, ostream e iostream, estás son las más utilizadas para el flujo de Entrada y Salida en C++.
La instrucción cin.clear(); borra y establece el flujo a goodbit; Cuando se establece gootbit todos los flags de error son limpiados.
La instrucción cin.ignore(1024, '\n') Ignorar hasta 1024 caractéres introducidos hasta encontrar un ENTER o viceversa, lo que primero ocurra.
La instrucción cin.fail() retorna true si una operación de flujo a fallado y es posiblie realizar una recuperación de esos errores.
La instrucción cin.rdstate() retorna true si el estado de flujo es correcto.
Espero este pequeño tip les sea de útilidad.
¿Sabes SQL? ¿No-SQL? Aprende MySQL, PostgreSQL, MongoDB, Redis y más con el Curso Profesional de Bases de Datos que empieza el martes, en vivo.
Por Freddie el 29 de Noviembre de 2010
Gracias
Por M@U el 30 de Noviembre de 2010
Freddie :
Por Freddie el 30 de Noviembre de 2010
M@U :
Freddie :
Por esutoraiki el 30 de Noviembre de 2010
Freddie :
M@U :
Freddie :
Por Freddie el 01 de Diciembre de 2010
esutoraiki :
Freddie :
M@U :
Freddie :
Por Otaku RzO el 02 de Diciembre de 2010
El mundo esta siendo un lugar mejor!
*Se une al abrazo grupal
Por Dreico el 26 de Febrero de 2011
Por ray el 06 de Marzo de 2011
Por esutoraiki el 11 de Marzo de 2011
Dreico-blog :
Por NiVlEm el 28 de Mayo de 2011
Por PETER el 18 de Septiembre de 2011
Por jose el 19 de Octubre de 2011
Por jose el 19 de Octubre de 2011
Por Granda90 el 21 de Noviembre de 2011
Por Jose el 01 de Marzo de 2012
Por Paola el 18 de Junio de 2012
Por Juan Pablo el 02 de Diciembre de 2012
Por javier el 13 de Marzo de 2013
Pero al tratar de enterder la logica pues me suigieros 2 dudas o cosas que no entiendo.
Como sabe "tu programa" que esta recibiendo letras y no numeros ?
Y, Que modificarias en el programa para ingresar numeros o numeros con punto decimal ?
Gracias
Por esutoraiki el 14 de Marzo de 2013
Intentare responderte paso por paso:
Pregunta: ¿Cómo sabe "tu programa" que esta recibiendo letras y no números ?
Respuesta: Existen dos respuestas la primera, esto es magia negra. La segunda como puedes observar estoy utilizando el objeto cin que es perteneciente a la clase istream. Este objeto posee unos flags para manejo de errores.
Existen errores que pueden ser pasados de alto y proseguir el programa, mientras otros no. Al declarar al inicio la variable "numero" se estableció que era de tipo int, puesto que es int si yo intento enviar un string a ella por medio de cin genera un error en su flujo ya que c++ no es de tipiado dinámico y por ende hace que los flags de error del objeto cin cambien de false a true, pero no es un error "fatal" por lo cual aún cuando el flujo se vio afectado puede proseguir el programa, por lo cual no se detiene. Aprovechando estas circunstancias se puede mandar el mensaje de error de tipo de datos.
Pregunta: ¿Qué modificarías en el programa para ingresar números o números con punto decimal ?
Respuesta: Para ingresar números, nada modificaría por que eso es lo que hace. Para que ingrese números con punto decimal definiría la variable numero como double así:
Código :
Por Ricardo el 23 de Abril de 2013
Por natanael el 03 de Septiembre de 2013
Por bgab_7 el 03 de Septiembre de 2013
Gracias
Por Jose Salazar el 10 de Octubre de 2013
Saludos!
Por Jimmy Ayala el 14 de Noviembre de 2013
int x;
do{
cin.clear();
cout<<"INGRESE EL ENTERO: "; fflush(stdin); cin>>x;
}while(cin.fail());
Por Carlos Hernández el 12 de Mayo de 2014
Por cristhian el 27 de Julio de 2014
Por venom_m el 21 de Octubre de 2014
Por Jorge el 27 de Octubre de 2014
Por brandon camacho el 30 de Marzo de 2015
asi
x=scanf("%d",&a);
if(x==true);
Por Dave el 09 de Mayo de 2015
Por Alepinedro el 05 de Julio de 2015
Por andrew el 21 de Septiembre de 2015
Por andrew el 21 de Septiembre de 2015
Por orbisoft el 05 de Octubre de 2015
Por yefer alvarez el 06 de Octubre de 2015
Por Jason el 03 de Febrero de 2016
Por Ramón Moreno el 22 de Mayo de 2016
Por kevin el 02 de Diciembre de 2016
Por Adro el 02 de Diciembre de 2016