2009-09-08 15 views
13

Estoy aprendiendo C y estoy usando "getchar()" para detener las ventanas de comandos para que pueda ver los ejercicios que estoy haciendo, pero simplemente no funciona. Aquí está una muestra:¿Por qué no getchar() espera a que presione enter después de scanf()?

#include <stdio.h> 

int main() 
{ 
    int value; 
    printf("1. option 1.\n2. option 2.\n3. option 3.\n4. Exit\n\nMake an option: "); 
    scanf("%d", &value); 
    switch (value) 
    { 
     case 1: 
      printf("you selected the option 1."); 
      break; 
     case 2: 
      printf("you selected the option 2."); 
      break; 
     case 3: 
      printf("you selected the option 3."); 
      break; 
     case 4: 
      printf("goodbye"); 
      break; 
     default: 
      printf("thats not an option"); 
      break; 
    } 
    getchar(); 
    return 0; 
} 

esta es la salida:

  1. opción 1.
  2. opción 2.
  3. opción 3.
  4. Salir.

Hacer una opción: 1

ha seleccionado la opción 1.

Proceso devuelto 0 (0x0) el tiempo de ejecución: 3.453 s

Pulse cualquier tecla para continuar.

¿Por qué no espera la entrada de "getchar()"?

+0

Ver http://stackoverflow.com/questions/1384073/problem-with-flushing-input-stream-c/1384089. –

Respuesta

2

¿Puede obtener getchar su retorno de carro que ingrese después del 1?

+0

Sí, getchar() está obteniendo la nueva línea que termina la entrada, y por lo tanto no espera mucho tiempo ya que los datos ya están en sus búferes. –

+0

Diablos si eso estuvo mal. Me gusta la respuesta fflush y la estoy probando. –

+1

Efectivamente, esos muchachos de flush estaban bien. –

21

Su scanf solo comió el número, pero no la línea nueva final. Poner una línea nueva o un espacio en blanco después del% d le dará el problema opuesto, leyendo demasiado lejos.

Es por eso que a la gente no le gusta scanf.

Sugeriría leer una línea real (use fgets(3)) y luego use sscanf() para escanear la cadena.

-9

para que su programa funcione, debe "vaciar" el flujo de entrada antes de llamar a getchar() con una llamada a fflush (stdin). Lo que hace es que, cuando teclea un número en el teclado y luego la tecla de retorno, el búfer de entrada obtiene ambos caracteres, por ejemplo '1' y '\ n', y su llamada a scanf solo obtiene '1' para que ' \ n 'permanece en el búfer de entrada. Cuando llamas a getchar, estás "obteniendo" el resto '\ n'. Vaciar la entrada descarta todo el buffer.

+3

'fflush (stdin)' es _undefined behavior_. No lo hagas –

+0

¿cómo debería hacerlo? soy realmente nuevo en esto, vengo de Python como mi primer lenguaje de programación así que todo acerca de la administración de la memoria es chino para mí ... –

+1

wow ... no sabía ... acabo de investigar y encontré esta explicación en http: // www.gidnetwork.com/b-57.html – nairdaen

2

El getchar() es la lectura de la \ n desde el teclado en scanf - ver here para obtener más información

1

Te pienso de entrada a Introduzca después de introducir "1". Será aceptado por el getchar(). Para que pueda resolver el problema simplemente agregue un getchar() adicional después del original (justo antes del return 0;).

** Probé esto y funcionó.

8

Antes que nada, do no use fflush() para borrar un flujo de entrada; el comportamiento es indefinido:

7.19.5.2.2 Si la ruta apunta a una secuencia de salida o una secuencia de actualización en la que no se ingresó la operación más reciente , la función fflush hace que los datos no escritos para la secuencia se entreguen al entorno de host para escribirse en el archivo; de lo contrario, el comportamiento es indefinido.

El problema es que el salto de línea final no está siendo consumida por el "% d" especificador de conversión, por lo que está siendo recogido inmediatamente por el getchar(). No hay una mejor manera de lidiar con esto, pero generalmente el enfoque es leer toda la línea como texto (usando fgets() o scanf() con un especificador de conversión de tamaño "% s"), que consumirá la nueva línea y luego convertirá al destino tipo de datos usando sscanf() o strtol() o strtod().

-2
#include <stdio.h> 
#include<conio.h> 
void main() 
{ 
    int value; 
    printf("1. option 1.\n2. option 2.\n3. option 3.\n4. Exit\n\nMake an option: "); 
    scanf("%d", &value); 
    switch (value) 
    { 
     case 1: 
      printf("you selected the option 1."); 
      break; 
     case 2: 
      printf("you selected the option 2."); 
      break; 
     case 3: 
      printf("you selected the option 3."); 
      break; 
     case 4: 
      printf("goodbye"); 
      break; 
     default: 
      printf("thats not an option"); 
      break; 
    } 
    getch(); 
} 
+0

Entonces, ¿su respuesta es usar 'getch' en su lugar? ¿Podrías dejarlo más claro (si es el caso)? –

2

que está recibiendo un retorno de carro, la forma en que lo haría llegar a su alrededor, defina un carbón de leña y sólo tiene que escanear el retorno de carro,

char ch; (antes de getch() introduzca la siguiente) scanf("%c",&ch); getchar();

debería funcionar de esta manera, no es la forma más eficiente de hacerlo pero funciona para mí.

1

Como ya se ha mencionado, scanf deja \ n atrás después de leer la entrada del usuario.

Soultion: agregar getchar() directamente después de scanf.

Compensa la deficiencia de scanf.

decir

int value; 
printf("1. option 1.\n2. option 2.\n3. option 3.\n4. Exit\n\nMake an option: "); 
scanf("%d", &value); 
getchar(); 
switch (value) 
Cuestiones relacionadas