C: múltiples escaneos, cuando ingreso un valor para un escaneo, omite el segundo escaneo

Tengo este bloque de código (se omiten las funciones porque la lógica es parte de una tarea)

#include  int main() { char c = 'q'; int size; printf("\nShape (l/s/t):"); scanf("%c",&c); printf("Length:"); scanf("%d",&size); while(c!='q') { switch(c) { case 'l': line(size); break; case 's': square(size); break; case 't': triangle(size); break; } printf("\nShape (l/s/t):"); scanf("%c",&c); printf("\nLength:"); scanf("%d",&size); } return 0; } 

Los primeros dos Scanf funcionan genial, no hay problema una vez que entramos en el ciclo while, tengo un problema donde, cuando se supone que se te pide que ingreses un nuevo carácter de forma, en su lugar salta a la printf de la Longitud y espera a tomar entrada desde allí para un char, luego un decimal en la siguiente iteración del ciclo.

Iteración preloop:

Scanf: Forma. Funciona genial
Scanf: Longitud. No hay problema

Loop 1.

Scanf: Forma. Se salta esto
Scanf: longitud. Problema, este scanf se asigna a la forma char.

Loop 2
Scanf: Forma. Se salta esto
Scanf: longitud. Problema, este scanf se asigna al tamaño int ahora.

¿Por qué está haciendo esto?

scanf("%c") lee el carácter de nueva línea desde la tecla ENTER .

Cuando escribe, digamos 15 , escribe un 1 , un 5 y luego presiona la tecla ENTER . Entonces ahora hay tres caracteres en el búfer de entrada. scanf("%d") lee el 1 y el 5 , interpretándolos como el número 15 , pero el carácter de nueva línea todavía está en el búfer de entrada. El scanf("%c") leerá inmediatamente este carácter de nueva línea y el progtwig pasará al siguiente scanf("%d") y esperará a que ingrese un número.

El consejo habitual es leer líneas enteras de entrada con fgets e interpretar el contenido de cada línea en un paso separado. Una solución más simple para su problema inmediato es agregar un getchar() después de cada scanf("%d") .

El problema básico es que scanf() deja la nueva línea después del número en el búfer y luego la lee con %c en la siguiente pasada. En realidad, esta es una buena demostración de por qué no uso scanf() ; Uso un lector de línea ( fgets() , por ejemplo) y sscanf() . Es más fácil de controlar.

Probablemente pueda rescatarlo usando " %c" lugar de "%c" para la cadena de formato. El espacio en blanco hace que scanf() omita el espacio en blanco (incluidas las líneas nuevas) antes de leer el caracter.

Pero a la larga será más fácil renunciar a scanf() y fscanf() y usar fgets() o equivalente más sscanf() . Aparte de todo lo demás, la generación de informes de errores es mucho más fácil cuando se tiene que trabajar con toda la cadena, no con los driblets que quedan detrás de scanf() después de que falla.

También debe, siempre, verificar que obtenga un valor convertido de scanf() . La entrada falla, de manera rutinaria y horrible. No dejes que arruine tu progtwig porque no lo has verificado.

Usa la función

 void seek_to_next_line( void ) { int c; while( (c = fgetc( stdin )) != EOF && c != '\n' ); } 

para limpiar tu buffer de entrada.

Intenta agregar un espacio en el escaneo.

 scanf(" %d", &var); // ^ // there 

Esto causará que scanf() descarte todos los espacios en blanco antes de hacer coincidir un entero.

Cuando escribe la forma y ENTER, la forma es consumida por el primer scanf, ¡pero el ENTER no lo es! El segundo scanf espera un número así, se omite el ENTER porque se considera un espacio en blanco, y el scanf espera una entrada válida (un número) que, de nuevo, finaliza con ENTER. Bueno, el número se consume, pero el ENTER no lo está, por lo que el primer scanf dentro del tiempo lo usa y se omite su mensaje de forma … este proceso se repite. Debe agregar otro% c en los scanfs para manejar la tecla ENTER. ¡Espero que esto ayude!

El carácter '\n' aún se deja en la secuencia de entrada después de que se completa la primera llamada a scanf , por lo que la segunda llamada a scanf() lee. Utilice getchar() .

También puede usar scanf("%c%*c", &c); leer dos caracteres e ignorar el último (en este caso ‘\ n’)