C: Múltiples scanf, cuando ingreso un valor para un scanf, se omite el segundo scanf [duplicado]

Resuelto Snow_Mac asked hace 12 años • 7 respuestas

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 printfLongitud 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?

Snow_Mac avatar Mar 05 '12 12:03 Snow_Mac
Aceptado

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

Cuando escribe, digamos 15, escribe a 1, a 5y luego presiona la ENTERtecla. Entonces ahora hay tres caracteres en el búfer de entrada. scanf("%d")lee el 1y 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 fgetse 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").

Thomas Padron-McCarthy avatar Mar 05 '2012 06:03 Thomas Padron-McCarthy

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 %cen 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.

Jonathan Leffler avatar Mar 05 '2012 07:03 Jonathan Leffler

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.

Jon Z. avatar Jun 18 '2015 21:06 Jon Z.

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.

noMAD avatar Mar 05 '2012 06:03 noMAD

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

Gargi Srinivas avatar Mar 05 '2012 06:03 Gargi Srinivas