Mi hermano recientemente comenzó a aprender C++. Él me contó un problema que encontró al intentar validar la entrada en un programa simple. Tenía un menú de texto donde el usuario ingresaba un número entero choice
, si ingresaban una opción no válida, se les pedía que la ingresaran nuevamente (hacer while loop). Sin embargo, si el usuario ingresara una cadena en lugar de una int, el código se rompería. leí varias preguntas sobre stackoverflow y le dijo que reescribir su código a lo largo de las líneas de:¿Cuál es la mejor manera de hacer la validación de entrada en C++ con cin?
#include<iostream>
using namespace std;
int main()
{
int a;
do
{
cout<<"\nEnter a number:"
cin>>a;
if(cin.fail())
{
//Clear the fail state.
cin.clear();
//Ignore the rest of the wrong user input, till the end of the line.
cin.ignore(std::numeric_limits<std::streamsize>::max(),\
'\n');
}
}while(true);
return 0;
}
Si bien esto funcionó bien, también probé algunas otras ideas:
1. El uso de un bloque de intento de captura. No funcionó. Creo que esto se debe a que una excepción no se plantea debido a una mala entrada. 2. Intenté if(! cin){//Do Something}
que tampoco funcionó. Todavía no he descubierto esto.
3. En tercer lugar, traté de ingresar una cadena de longitud fija y luego analizarla. Yo usaría atoi(). ¿Es compatible y compatible con los estándares? ¿Debo escribir mi propia función de análisis?
4. Si escribe una clase que usa cin, pero realiza este tipo de detección de error dinámicamente, tal vez determinando el tipo de la variable de entrada en tiempo de ejecución, ¿tendría demasiada sobrecarga? ¿Es posible?
Me gustaría saber cuál es la mejor manera de hacer este tipo de comprobación, ¿cuáles son las mejores prácticas?
Me gustaría agregar que, aunque no soy nuevo en la escritura de código C++, soy nuevo en la redacción de código compatible con los estándares. Estoy tratando de desaprender las malas prácticas y aprender las correctas. Me agradaría mucho que los contestadores brinden una explicación detallada.
EDIT: Veo que litb ha respondido a una de mis ediciones anteriores. Voy a publicar ese código aquí para referencia.
#include<iostream>
using namespace std;
int main()
{
int a;
bool inputCompletionFlag = true;
do
{
cout<<"\nEnter a number:"
cin>>a;
if(cin.fail())
{
//Clear the fail state.
cin.clear();
//Ignore the rest of the wrong user input, till the end of the line.
cin.ignore(std::numeric_limits<std::streamsize>::max(),\
'\n');
}
else
{
inputCompletionFlag = false;
}
}while(!inputCompletionFlag);
return 0;
}
Este código falla en la entrada como "1asdsdf". No sabía cómo solucionarlo, pero litb ha publicado una gran respuesta. :)
Gracias por la explicación detallada, pero miré hacia arriba y encontré que Boost no es una biblioteca estándar. A la luz de eso, ¿sería mejor rodar mi propio código si puedo o debo seguir con el impulso? – batbrat
Acabo de notar que se va a estandarizar en gran medida en C++ 0x. Entonces usaré Boost. Me alegrará si confirmas. Gracias. – batbrat
Sí, el próximo C++ incluirá algunas bibliotecas diseñadas después de las de refuerzo (shared_ptr, thread, system (error_code, ...), array, bind, function). pero no date_time Sin embargo, es muy recomendable impulsarlo. es mejor que rodar tu propia realidad –