Estoy intentando hacer una función que pida un numero del 0 al 9 al usuario y que sea robusta. He estado mirando códigos para guiarme y la mayoría fallan al encontrarse con alguna de estas situaciones, normalmente debido al uso de cin:
1- Si el usuario introduce espacios antes del numero o después, la entrada es válida
2- Si se pulsa control+z (eof en windows) se produce un ciclo infinito o la entrada se da como válida
3- Si el usuario tipeo 2ff la entrada resulta válida
4- La entrada se queda esperando a que tecleemos algo por culpa de algún salto de línea
He hecho el siguiente código, creo que soluciona los problemas comentados anteriormente. Me gustaría saber su opinión y si creen en algún caso dónde podría fallar o si puedo mejorarlo.
int pedir_numero()
{
string data = "";
while (true)
{
cout << "Introduce una opcion: ";
if (!getline(cin, data))
{
return -1;
}
if (data.length() != 1 || isspace(data[0]))
{
cerr << "Numero invalido, vuelve a intentarlo!" << endl;
continue;
}
try
{
return stoi(data);
}
catch (const exception &e)
{
cerr << "Numero invalido, vuelve a intentarlo!" << endl;
}
}
}
Una variante, un poco más simple, creo:
int pedir_numero()
{
cout << "Introduce una opcion: ";
string data{};
while (getline(cin, data))
{
if (data.length() != 1 || !isdigit(data[0])) // isdigit() sabe si es 0...9
{
// cerr se prefiere para mensaje de error que suelen ir a auditoría,
// quizá aquí mejor cout.
// y no uses endl, si realmente lo necesitas es porque hay algo muy raro
// en tu sistema.
cout << "Numero invalido, vuelve a intentarlo!\n";
continue;
}
// si llegó hasta aquí es un número de un solo dígito,
return data[0] - '0';
}
return -1;
}
Gracias por aportar una alternativa