C: Múltiples scanf, cuando ingreso un valor para un scanf, se omite el segundo scanf [duplicado]
Tengo este bloque de código (funciones omitidas ya que la lógica es parte de una tarea):
#include <stdio.h>
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 dos primeros Scanf funcionan muy bien, no hay problema una vez que entramos en el ciclo while, tengo un problema donde, cuando se supone que se le solicita que ingrese un nuevo carácter de forma, salta a printf
Longitud y espera recibir entrada. desde allí para un carácter, luego un decimal en la siguiente iteración del ciclo.
Iteración previa al bucle:
Scanf: Forma. Funciona muy bien
Scanf: Longitud. Ningún problema
Bucle 1.
Scanf: Forma. Salta este
Scanf: longitud. Problema, este escaneo se asigna al carácter de forma.
Bucle 2
Scanf: Forma. Salta este
Scanf: longitud. Problema, este scanf ahora se asigna al tamaño int.
¿Por qué hace esto?
scanf("%c")
lee el carácter de nueva línea de la ENTERclave.
Cuando escribe, digamos 15
, escribe a 1
, a 5
y luego presiona la ENTERtecla. 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. Inmediatamente leerá scanf("%c")
este carácter de nueva línea y el programa pasará al siguiente scanf("%d")
y esperará a que ingrese un número.
El consejo habitual es leer líneas completas de entrada con fgets
e interpretar el contenido de cada línea en un paso separado. Una solución más sencilla a su problema inmediato es agregar un getchar()
después de cada uno 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 %c
en la siguiente pasada. En realidad, esta es una buena demostración de por qué no uso scanf()
; Utilizo un lector de líneas ( fgets()
, por ejemplo) y sscanf()
. Es más fácil de controlar.
Probablemente puedas rescatarlo usando " %c"
en lugar "%c"
de la cadena de formato. El espacio en blanco hace scanf()
que se omitan espacios en blanco (incluidas las nuevas líneas) antes de leer el carácter.
Pero a la larga será más fácil renunciar scanf()
a fscanf()
y usar fgets()
un plus equivalente sscanf()
. Aparte de todo lo demás, el informe de errores es mucho más fácil cuando tienes toda la cadena con la que trabajar, no las gotas que quedan scanf()
después de que falla.
También debes comprobar siempre que obtienes un valor convertido de scanf()
. La entrada falla, de manera rutinaria y horrible. No dejes que arruine tu programa porque no lo comprobaste.
Intente agregar un espacio en el archivo scanf.
scanf(" %d", &var);
// ^
// there
Esto hará scanf()
que se descarten todos los espacios en blanco antes de hacer coincidir un número entero.
Usa la función
void seek_to_next_line( void )
{
int c;
while( (c = fgetc( stdin )) != EOF && c != '\n' );
}
para borrar su búfer de entrada.
El '\n'
carácter aún permanece en el flujo de entrada después de que scanf
se completa la primera llamada a, por lo que la segunda llamada a scanf()
lo lee. Utilice getchar()
.