usar teclas tecla salto para linea leer direccion con como codigo capturar c getchar

teclas - Cómo evitar presionar enter con getchar()



menu con teclas de direccion en c++ (10)

Esta es una pregunta "novato" para el lenguaje de programación C:

En el siguiente código:

#include <stdio.h> int main(void) { int c; while ((c=getchar())!= EOF) putchar(c); return 0; }

Tengo que presionar Enter para imprimir todas las letras que getchar con getchar , pero no quiero hacer esto, lo que quiero hacer es presionar la letra e inmediatamente ver la letra que introduje repetida sin presionar Enter . Por ejemplo, si presiono la letra ''a'', quiero ver otra ''a'' al lado, y así sucesivamente:

aabbccddeeff.....

Pero cuando presiono ''a'' no pasa nada, puedo escribir otras letras y la copia aparece solo cuando presiono Enter :

abcdef abcdef

¿Cómo puedo hacer esto?

Estoy usando el comando cc -o example example.c en Ubuntu para compilar.


Dado que está trabajando en un derivado de Unix (Ubuntu), esta es una forma de hacerlo, no recomendada, pero funcionará (siempre que pueda escribir comandos con precisión):

echo "stty -g $(stty -g)" > restore-sanity stty cbreak ./your_program

Use interrupt para detener el programa cuando esté aburrido con él.

sh restore-sanity

  • La línea ''eco'' guarda la configuración actual del terminal como un script de shell que los restaurará.
  • La línea ''stty'' desactiva la mayor parte del procesamiento especial (por lo que Control-D no tiene ningún efecto, por ejemplo) y envía caracteres al programa tan pronto como estén disponibles. Significa que ya no puedes editar tu tipeo.
  • La línea ''sh'' restablece la configuración de terminal original.

Puede economizar si ''stty cuerdo'' restaura su configuración con la suficiente precisión para sus propósitos. El formato de ''-g'' no es portátil en todas las versiones de ''stty'' (por lo que lo que se genera en Solaris 10 no funcionará en Linux, o viceversa), pero el concepto funciona en todas partes. La opción ''sty cuerdo'' no está disponible universalmente, AFAIK (pero está en Linux).


De forma predeterminada, la biblioteca C almacena en búfer el resultado hasta que ve un retorno. Para imprimir los resultados de inmediato, use fflush :

while((c=getchar())!= EOF) { putchar(c); fflush(stdout); }


En un sistema Linux, puede modificar el comportamiento del terminal usando el comando stty . Por defecto, el terminal guardará toda la información hasta que presione Enter , antes de enviarlo al programa C.

Un ejemplo rápido, sucio y no especialmente portátil para cambiar el comportamiento desde el propio programa:

#include<stdio.h> int main(void){ int c; /* use system call to make terminal send all keystrokes directly to stdin */ system ("/bin/stty raw"); while((c=getchar())!= ''.'') { /* type a period to break out of the loop, since CTRL-D won''t work raw */ putchar(c); } /* use system call to set terminal behaviour to more normal behaviour */ system ("/bin/stty cooked"); return 0; }

Tenga en cuenta que esto no es realmente óptimo, ya que simplemente asume que el comportamiento stty cooked es el que se desea cuando el programa sale, en lugar de verificar cuál era la configuración del terminal original. Además, dado que todos los procesos especiales se omiten en modo raw, muchas secuencias de teclas (como CTRL-C o CTRL-D ) en realidad no funcionarán como espera sin un procesamiento explícito en el programa.

Puede ser man stty para tener más control sobre el comportamiento del terminal, dependiendo exactamente de lo que desee lograr.


Esto depende de su sistema operativo, si se encuentra en un entorno similar a UNIX, el indicador ICANON está habilitado de manera predeterminada, por lo que la entrada se almacena temporalmente hasta el próximo ''/n'' o EOF . Al deshabilitar el modo canónico obtendrá los caracteres inmediatamente. Esto también es posible en otras plataformas, pero no existe una solución directa multiplataforma.

EDITAR: veo que especificó que usa Ubuntu. Acabo de publicar algo similar ayer, pero tenga en cuenta que esto deshabilitará muchos comportamientos predeterminados de su terminal.

#include<stdio.h> #include <termios.h> //termios, TCSANOW, ECHO, ICANON #include <unistd.h> //STDIN_FILENO int main(void){ int c; static struct termios oldt, newt; /*tcgetattr gets the parameters of the current terminal STDIN_FILENO will tell tcgetattr that it should write the settings of stdin to oldt*/ tcgetattr( STDIN_FILENO, &oldt); /*now the settings will be copied*/ newt = oldt; /*ICANON normally takes care that one line at a time will be processed that means it will return if it sees a "/n" or an EOF or an EOL*/ newt.c_lflag &= ~(ICANON); /*Those new settings will be set to STDIN TCSANOW tells tcsetattr to change attributes immediately. */ tcsetattr( STDIN_FILENO, TCSANOW, &newt); /*This is your part: I choose ''e'' to end input. Notice that EOF is also turned off in the non-canonical mode*/ while((c=getchar())!= ''e'') putchar(c); /*restore the old settings*/ tcsetattr( STDIN_FILENO, TCSANOW, &oldt); return 0; }

Notarás que cada personaje aparece dos veces. Esto se debe a que la entrada se repite inmediatamente en el terminal y luego su programa la vuelve a poner también con putchar() . Si desea desasociar la entrada de la salida, también debe girar la bandera ECHO. Puedes hacer esto simplemente cambiando la línea apropiada a:

newt.c_lflag &= ~(ICANON | ECHO);


He tenido este problema / pregunta en una tarea en la que estoy trabajando actualmente. También depende de la entrada de la que está obteniendo. estoy usando

/dev/tty

para obtener entrada mientras el programa se está ejecutando, por lo que debe ser la cadena de archivos asociada con el comando.

En la máquina ubuntu que tengo que probar / orientar, se requiere algo más que solo

system( "stty -raw" );

o

system( "stty -icanon" );

Tuve que agregar el indicador --file, así como la ruta al comando, así:

system( "/bin/stty --file=/dev/tty -icanon" );

Todo es copacetic ahora.


I / O es una función del sistema operativo. En muchos casos, el sistema operativo no pasará caracteres escritos a un programa hasta que se presione ENTER. Esto permite al usuario modificar la entrada (como el retroceso y volver a escribir) antes de enviarlo al programa. Para la mayoría de los propósitos, esto funciona bien, presenta una interfaz consistente para el usuario y alivia al programa de tener que lidiar con esto. En algunos casos, es deseable que un programa obtenga caracteres de las teclas a medida que se presionan.

La biblioteca C se ocupa de los archivos y no se ocupa de cómo ingresan los datos en el archivo de entrada. Por lo tanto, no hay forma en el lenguaje en sí para obtener claves mientras se presionan; en cambio, esto es específico de la plataforma. Como no ha especificado el sistema operativo o el compilador, no podemos buscarlo por usted.

Además, la salida estándar normalmente se amortigua para mayor eficiencia. Esto es hecho por las bibliotecas C, y entonces hay una solución C, que es fflush(stdout); después de cada personaje escrito. Después de eso, si los caracteres se muestran inmediatamente depende del sistema operativo, pero todos los sistemas operativos con los que estoy familiarizado mostrarán la salida de inmediato, por lo que normalmente no es un problema.


Me gusta la respuesta de Lucas, pero me gustaría explicarlo un poco. Hay una función termios.h en termios.h llamada cfmakeraw() que el hombre describe como:

cfmakeraw() sets the terminal to something like the "raw" mode of the old Version 7 terminal driver: input is available character by character, echoing is disabled, and all special processing of terminal input and output characters is disabled. [...]

Esto básicamente hace lo mismo que sugirió Lucas y más, puedes ver las banderas exactas que establece en las páginas man: termios(3) .

Caso de uso

int c = 0; static struct termios oldTermios, newTermios; tcgetattr(STDIN_FILENO, &oldTermios); newTermios = oldTermios; cfmakeraw(&newTermios); tcsetattr(STDIN_FILENO, TCSANOW, &newTermios); c = getchar(); tcsetattr(STDIN_FILENO, TCSANOW, &oldTermios); switch (c) { case 113: // q printf("/n/n"); exit(0); break; case 105: // i printf("insert/n"); break; default: break;


Puede incluir la biblioteca ''ncurses'' y usar getch() lugar de getchar() .


getchar () es una función estándar que en muchas plataformas requiere presionar ENTER para obtener la entrada, porque la plataforma almacena la entrada hasta que se presione esa tecla. Muchos compiladores / plataformas son compatibles con el getch no estándar () que no se preocupa por ENTRAR (omite el almacenamiento en búfer de la plataforma, trata el ENTRAR como simplemente otra tecla).


sí, puedes hacer esto en Windows también, aquí está el código a continuación, usando la biblioteca conio.h

#include <iostream> //basic input/output #include <conio.h> //provides non standard getch() function using namespace std; int main() { cout << "Password: "; string pass; while(true) { char ch = getch(); if(ch==''/r''){ //when a carriage return is found [enter] key cout << endl << "Your password is: " << pass <<endl; break; } pass+=ch; cout << "*"; } getch(); return 0; }