El uso de getchar () en c obtiene el ‘Enter’ después de la entrada [duplicate]
⏰ 4 minutos de lectura
Boca de dragón
Estoy tratando de escribir un programa simple que le pida al usuario que elija de un menú en un bucle. Uso getchar () para obtener la entrada, sin embargo, noté que cuando ingreso un carácter y presiono ‘Enter’, el programa hace dos bucles (como si presionara dos veces) uno el char como entrada y otro para ‘Enter’ como entrada.
¿Cómo puedo solucionar esto?
getchar() devuelve el primer carácter en el búfer de entrada y lo elimina del búfer de entrada. Pero otros caracteres todavía están en el búfer de entrada (\n en tu ejemplo). Debe borrar el búfer de entrada antes de llamar getchar() otra vez:
void clearInputBuffer() // works only if the input buffer is not empty
{
do
{
c = getchar();
} while (c != '\n' && c != EOF);
}
jaredpar
La forma más sencilla es filtrar la tecla Intro como el valor de retorno de getchar
char c = (char)getchar();
if ( c != '\n' ) {
...
}
Supongo que quisiste decir getchar()? si es así, getchar() devuelve int.
@Jared: sí, pero char está limitado a (normalmente) 256 valores, y necesita (normalmente) 257 valores para identificar TODOS caracteres Y FEO. Es por eso getchar() devuelve un int
– pmg
19 de octubre de 2010 a las 15:54
@pmg, soy consciente de eso. Simplemente estoy demostrando lo que solicitó el OP (cómo verificar la nueva línea).
– JaredPar
19 de octubre de 2010 a las 15:59
Ok, pero puedes demostrar con int c también 🙂
– pmg
19 de octubre de 2010 a las 17:13
Agrega un getchar() después de la getchar() :PAGS
Supongo que funcionaría, pero es un anestésico silencioso.
– Snapdragon
20 de octubre de 2010 a las 18:02
Eso producirá problemas en algunos casos en los que el usuario tendrá que presionar regresar dos veces.
– Kaitán
5 mayo 2017 a las 0:00
Qué tal si
#include <stdio.h>
/*! getline() reads one line from standard input and copies it to line array
* (but no more than max chars).
* It does not place the terminating \n in line array.
* Returns line length, or 0 for empty line, or EOF for end-of-file.
*/
int getline(char line[], int max)
{
int nch = 0;
int c;
max = max - 1; /* leave room for '\0' */
while ((c = getchar()) != EOF) {
if (c == '\n')
break;
if (nch < max) {
line[nch] = c;
nch = nch + 1;
}
}
if (c == EOF && nch == 0)
return EOF;
line[nch] = '\0';
return nch;
}
Has respondido a tu propia pregunta; tienes que lidiar con el carácter de nueva línea de alguna manera.
Hay varias opciones. Si sus opciones de menú son numeradopuedes usar scanf() para leer en un valor entero y cambiar basado en eso:
printf("Pick an option: ");
fflush(stdout);
scanf("%d", &option);
switch(option)
{
case 0 : do_something(); break;
case 1 : do_something_else(); break;
...
default: bad_option(); break;
}
La ventaja de esta opción es que el %d El especificador de conversión omite cualquier espacio en blanco inicial, incluidos los caracteres de nueva línea, por lo que no tiene que preocuparse por ningún espacio sin leer. \n obstruyendo el flujo de entrada (de hecho, la mayoría de los especificadores de conversión omiten los espacios en blanco iniciales; %c no lo hace, haciendo que se comporte mucho como getchar()).
La desventaja de esta opción es que si alguien toca un carácter que no es un dígito en su entrada, no se leerá con el %d especificador de conversión, y permanecerá atascado en el flujo de entrada hasta que una llamada a getchar() o scanf() con un %s o %c especificador de conversión.
Una mejor opción es leer todas las entradas como caracteres. instrumentos de cuerda utilizando fgets()luego analice y valide según sea necesario.
/**
* Prints a prompt to stdout and reads an input response, writing
* the input value to option.
*
* @param prompt [in] - prompt written to stdout
* @param option [out] - option entered by user
*
* @return - 1 on success, 0 on failure. If return value is 0, then option
* is not changed.
*/
int getOption(const char *prompt, char *option)
{
char input[3]; // option char + newline + 0 terminator
int result = 0;
printf("%s: ", prompt);
fflush(stdout);
if (fgets(input, sizeof input, stdin))
{
/**
* Search for a newline character in the input buffer; if it's not
* present, then the user entered more characters than the input buffer
* can store. Reject the input, and continue to read from stdin until
* we see a newline character; that way we don't leave junk in the
* input stream to mess up a future read.
*/
char *newline = strchr(input, '\n');
if (!newline)
{
printf("Input string is too long and will be rejected\n");
/**
* Continue reading from stdin until we find the newline
* character
*/
while (!newline && fgets(input, sizeof input, stdin))
newline = strchr(input, '\n');
}
else
{
*option = input[0];
result = 1;
}
}
else
printf("Received error or EOF on read\n");
return result;
}
Sí, eso es mucho trabajo para leer en una estúpida opción de menú, y esa es la versión simple. Bienvenido al maravilloso mundo del procesamiento de entrada interactivo en C.
¿Ha sido útil esta solución?
Tu feedback nos ayuda a saber si la solución es correcta y está funcionando. De esta manera podemos revisar y corregir el contenido.
Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos.
Configurar y más información