2012-01-13 22 views
9

Escribo aplicación de consola que realiza varias scanf para int Y después, lo realiza getchar:lectura carbón desde la consola

int x,y; 
char c; 
printf("x:\n"); 
scanf("%d",&x); 
printf("y:\n"); 
scanf("%d",&y); 
c = getchar(); 

como consecuencia de este recibo c = '\n', a pesar de la entrada es:

1 
2 
a 

¿Cómo se puede resolver este problema?

+4

'getchar()' devuelve 'int', no' char'. – unwind

+0

@unwind - "Devuelve el siguiente carácter de la entrada estándar (stdin)." - ascii para char – Yakov

Respuesta

12

Esto se debe a que scanf deja la nueva línea que ingresa en la secuencia de entrada. Trate

do 
    c = getchar(); 
while (isspace(c)); 

en lugar de

c = getchar(); 
1

Para empezar, la scanf debe leer scanf("%d\n", &x); o y. Eso debería hacer el truco.

man scanf

+0

No funciona: después de ingresar 1, no escribe "y:" (ver el ejemplo actualizado), pero espera el segundo número y solo después de que escriba "y": – Yakov

1

Call fflush(stdin); después de scanf para descartar los caracteres innecesarios (como \ r \ n) de memoria intermedia de entrada que fueron dejados por scanf.

Editar: Como los chicos en los comentarios mencionados fflush solución podría tener un problema de portabilidad, así que aquí está mi segunda propuesta. No use scanf en absoluto y realice este trabajo utilizando la combinación de fgets y sscanf. Este es un enfoque mucho más seguro y simple, porque permite manejar situaciones de entrada incorrectas.

int x,y; 
char c; 
char buffer[80]; 

printf("x:\n"); 
if (NULL == fgets(buffer, 80, stdin) || 1 != sscanf(buffer, "%d", &x)) 
{ 
    printf("wrong input"); 
} 
printf("y:\n"); 
if (NULL == fgets(buffer, 80, stdin) || 1 != sscanf(buffer, "%d", &y)) 
{ 
    printf("wrong input"); 
} 
c = getchar(); 
+0

-1 'fflush (stdin)' no está definido. Incluso [Microsoft/MSDN] (http://msdn.microsoft.com/en-us/library/9yky46tz%28v=vs.71%29.aspx) (que define una construcción así) dice (aunque en un lugar oculto) es una extensión: "// fflush en la secuencia de entrada es una extensión del estándar C". – pmg

+0

@pmg: ¡Es cierto! (Incluso tiendo a señalarlo de vez en cuando). Esto aparece un poco en SO., Pero * funciona * MSDN admite (ha vinculado la página) y también lo hace [Linux] (http://linux.die.net/man/3/fflush) ... '" Para flujos de entrada, fflush() descarta cualquier información almacenada en el búfer que se haya extraído del archivo subyacente, pero la aplicación no la ha consumido ... Los estándares no especifican el comportamiento de las secuencias de entrada. La mayoría de las otras implementaciones se comportan igual como Linux. "... ¿Qué tan malo es usar en el código? –

+0

El texto en [POSIX.1-2008 página] (http://pubs.opengroup.org/onlinepubs/9699919799/functions/fflush.html) es ligeramente diferente: no menciona la aplicación en absoluto. No me gusta esa descripción POSIX.1-2008 en absoluto. Linux y Windows y POSIX (con todas las advertencias) no son suficientes para llamarlo portátil. – pmg

2

Una manera de limpiar anyspace antes de carbón deseada y simplemente ignorar los caracteres restantes es

do { 
    c = getchar(); 
} while (isspace(opcao)); 
while (getchar() != '\n'); 
2

Usted puede utilizar la función fflush para borrar cualquier cosa a la izquierda en tampón como consquence de la línea de comand anterior entradas:

fflush(stdin); 
+2

'fflush (stdin)' invoca Comportamiento no definido según el estándar C, aunque está bien definido en algunos sistemas (implementaciones), pero es mejor evitarlo para mejorar la portabilidad. –

Cuestiones relacionadas