Programación General > C/C++

 validar entero para seleccion de un menu

(1/2) > >>

kurtjavier:
Hola como estan todos, soy nuevo aqui en el foro, estuve buscando algun foro de programacion en c++ y me tope con este....vamos a ver que tal me va por aca.

El hecho es que no se nada de excepciones en c++, tengo el libro de Programacion en c++ 2da edicion de joyanes donde hablan del tema pero no entiendo mucho. Bueno lo que estoy buscando por ahora es muy sencillo, practicando listas doblemente enlazadas he creado un programa para manejar una agenda telefonica, con la posibilidad de cargar la agenda desde un archivo a la lista y tambien guardar la agenda a un archivo desde la lista enlazada.

En el programa tengo varios menu donde el usuario selecciona una opcion leo el entero y ejecuto lo que el usuario ingresa, el problema viene cuando el usuario no ingresa un numero sino que ingresa una letra o un simbolo o un valor mayor a la capacidad de un entero, provocando un error, mi menu simplemente dice opcion invalida pero se ejecuta infinitamente por la misma condicion de un while que tengo no se para, por lo menos en java se como tratar estos problemas con excepciones, pero en c++ no tengo ni idea, si alguien puede darme una mano. aqui les dejo codigo del primer menu nada mas.


--- Código: C++ --- int menu(){    int opc=0;    system ("cls");    do    {        cout<<"nn1.Agregar contacton2.Eliminar contacton3.Buscar contacton4.Buscar multiples contactosn5.Listar todon6.Cargar agenda desde archivon7.Guardar agenda a archivon8.Salir"<<endl;        cin>>opc;        if(opc>0&&opc<9)            return opc;        else            cout<<"nOpcion invalida"<<endl;    }while(true);    return 8;}  
cuando lee mal repite el do por la misma condicion del while pero no se para en el menu para leer la opcion sino que sigue sin pararse. Por lo menos en java manejo la excepcion en un bloque try y catch facil, pero c++ trato de hacerlo igual que he leido se puede hacer y no funciona, si ingreso una letra o un simbolo dice opcion invalida pero el menu se ejecuta infinitamente por el true del while. Trato limpiando el buffer de entrada pero tampoco. Bueno espero alguien me eche una mano por aca saludos

kurtjavier:
ok buscando y buscando encontre que taba buscando mal debi bucar sobre validacion de un entero, y bueno buscando sobre eso encontre como manejar el error cuando se introduce un simbolo:


--- Código: C++ --- int menu(){    int opc=0;    system ("cls");    do    {        cout<<"nn1.Agregar contacton2.Eliminar contacton3.Buscar contacton4.Buscar multiples contactosn5.Listar todon6.Cargar agenda desde archivon7.Guardar agenda a archivon8.Salir"<<endl;        cin>>opc;        cin.ignore(numeric_limits<int>::max(), 'n');        if (!cin || cin.gcount() != 1)        {            cout<<"nNo valido"<<endl;            cin.clear();            opc=0;        }        if(opc>0&&opc<9)            return opc;        else            cout<<"nOpcion invalida"<<endl;    }while(true);    return 8;}  
si no lee un entero muetra el mensaje NO VALIDO limpia hago opc=0 y sigo el while se ejecuta nuevamente por el true esta bien, y muestra el menu y se para para que el usuario ingrese otra opcion, pero si introduzco una letra se muestra en mensaje de error igual se limpia pero no se para siguemostrando el menu y com osi estuviera leyendo la letra otra ves indefinidamente, porque pasa esto con ua letra y no con un simbolo como seria la forma correcta de manejar ese error sea lo que sea que se introduzca mientras no sea un entero :S

Eternal Idol:
Bueno, como ya viste esto no tiene nada que ver con las excepciones, no se produce ninguna. Si llamas a clear ANTES del ignore te va a funcionar bien tambien con letras, sino ya esta puesto el flag failbit en el stream (por la letra) y entonces ignore no hace nada.

kurtjavier:

--- Cita de: "Eternal Idol" ---Bueno, como ya viste esto no tiene nada que ver con las excepciones, no se produce ninguna. Si llamas a clear ANTES del ignore te va a funcionar bien tambien con letras, sino ya esta puesto el flag failbit en el stream (por la letra) y entonces ignore no hace nada.
--- Fin de la cita ---

si como en java se maneja como excepcion asi lo estaba buscando para c++ y bueno ya vi como hacerlo mmm de una manera digamos que funciona pero no se si es la mas correcta:


--- Código: C++ --- int menu(){    int opc=0;    system ("cls");    do    {        cout<<"nn1.Agregar contacton2.Eliminar contacton3.Buscar contacton4.Buscar multiples contactosn5.Listar todon6.Cargar agenda desde archivon7.Guardar agenda a archivon8.Salir"<<endl;        while(!(cin>>opc))        {            cout<<"nNo valido"<<endl;            cin.clear();            cin.ignore(numeric_limits<streamsize>::max(), 'n');        }        if(opc>0&&opc<9)            return opc;        else            cout<<"nOpcion invalida"<<endl;    }while(true);    return 8;}  
Con la condicion del while anidado dentro del do-while  si la entrada no fue correcta  "if(!(cin>>opc))" llamamos al clear para que limpie, quitamos de la entrada lo que se leyo para que no siga causando problemas, en este caso no le especifico que es de tamañ ode un entero sino que tome todo el tamaño de lo que esta en la entrada "cin.ignore(numeric_limits<streamsize>::max(), 'n');" y vuelve a esperar la nueva lectura, de ese modo cunado se lea el entero si seguira sin problemas.

saque la informacion de aqui  " augustcouncil.com/~tgibson/tutorial/iotips.html "  esta buena la pagina ...

Eternal Idol:
Yo usaria sync en lugar de ignore.

Navegación

[0] Índice de Mensajes

[#] Página Siguiente

Ir a la versión completa