[C con Clase] Dudas con printf y scanf

Apokathastasis apokathastasis en gmail.com
Dom Dic 30 11:32:16 CET 2007


On 12/29/07, JoseL <joselubar en gmail.com> wrote:
> Hola,
>
> Estoy con los primeros capítulos del curso y he empezado a mirar también algunas funciones de las librerías estándar. Concretamente estaba experimentando con printf y scanf, con la idea de escribir un prototipo de programa que muestre opciones y se reinicie indefinidamente hasta que el usuario seleccione expresamente la opción 'salir'. Más o menos así:
>
>
> #include <cstdio>
> #include <cstdlib>
>
> int main()
> {
>         char opcion;
>
>         /* Este bucle se repetirá indefinidamente mientras no se elija
>            opción 'salir' (opcion == '4') */
>
>         while(true)
>         {
>                 printf("\n\n\t--- MENU PRINCIPAL ---\n\n");
>
>                 printf(" 1 - Hacer una primera cosa\n");
>                 printf(" 2 - Hacer una segunda cosa\n");
>                 printf(" 3 - Hacer una tercera cosa\n");
>                 printf(" 4 - Salir\n\n");
>
>                 printf(" Introduce una opcion: ");
>                 scanf("%c", &opcion);
>
>                 switch(opcion)
>                 {
>                         case '1':
>                         {
>                                 printf("\n\tCodigo para la opcion '1'...\n");
>                                 break;
>                         }
>                         case '2':
>                         {
>                                 printf("\n\tCodigo para la opcion '2'...\n");
>                                 break;
>                         }
>                         case '3':
>                         {
>                                 printf("\n\tCodigo para la opcion '3'...\n");
>                                 break;
>                         }
>                         case '4': return 0;
>                                 // La única opción para finalizar el programa.
>
>                         default:
>                                 printf("\n\n Debe introducir una opcion valida\n");
>                 }
>
>         printf("\n Presione cualquier tecla para volver al menu principal...\n");
>         system("pause>null");
>         }
> }
>
> El caso es que no se comporta como yo esperaba. Mejor me explico mostrando lo que aparece en la consola:
>
>
>          --- MENU PRINCIPAL ---
>
>     1 - Hacer una primera cosa
>     2 - Hacer una segunda cosa
>     3 - Hacer una tercera cosa
>     4 - Salir
>
>     Introduce una opcion: 1
>           [Tecleo 1 y pulso INTRO]
>
>           Codigo para la opcion '1'...
>
>     Presione cualquier tecla para volver al menu principal...
>           [Pulso INTRO]
>
>
>          --- MENU PRINCIPAL ---
>
>     1 - Hacer una primera cosa
>     2 - Hacer una segunda cosa
>     3 - Hacer una tercera cosa
>     4 - Salir
>
>     Introduce una opcion:
>           [Debería pararse aquí, pero no se detiene, y se comporta como si]
>            hubiera introducido una opción no válida:]
>
>     Debe introducir una opcion valida
>
>     Presione cualquier tecla para volver al menu principal...
>           [Pulso INTRO]
>
>
>          --- MENU PRINCIPAL ---
>
>     1 - Hacer una primera cosa
>     2 - Hacer una segunda cosa
>     3 - Hacer una tercera cosa
>     4 - Salir
>
>     Introduce una opcion: 4
>           [Ahora si se detiene]
>
>
> A ver si alguien me puede explicar qué debería hacer para que el programa funcione correctamente.
>
> Gracias y un saludo.
> _______________________________________________
> Lista de correo Cconclase Cconclase en listas.conclase.net
> http://listas.conclase.net/mailman/listinfo/cconclase_listas.conclase.net
> Bajas: http://listas.conclase.net/index.php?gid=2&mnu=FAQ
>

Hola:

El problema que tienes se debe al manejo que das al buffer de entrada
(stdin o standard input). Para entenderlo mejor te lo ilustraré con tu
propio ejemplo.

* Cuando aparece el menu tecleas 2 caracteres 1 e INTRO ('\n') los
cuales quedan en stdin.
* Después lees *un* solo caracter, por lo que el INTRO queda en stdin.
* Cuando se ejecuta el ciclo por segunda vez llevas acarreando un
INTRO por lo que al llegar al scanf es el caracter que lee.
* Cuando se ejecuta el ciclo por tercera vez se detiene porque ya no
hay nada en stdin y entonces scanf vuelve a esperar una entrada.

Para solucionar esto puedes utilizar la función fflush() con stdin
como argumento después de scanf.

-- 
"Meu braço o coraçâo te arrancar
Para com o meu fundo horror melhor te penetrar."

ἀποκατάστασις - restitutio in pristinum statum


Más información sobre la lista de distribución Cconclase