select stdin blocking ncurses curses

select - ncurses y stdin blocking



(1)

Tengo stdin en un conjunto de select() y quiero tomar una cadena de stdin cada vez que el usuario lo escribe y pulsa Enter .

Pero select activa el stdin como listo para leer antes de presionar Enter y, en casos excepcionales, antes de que se escriba nada. Esto cuelga mi programa en getstr() hasta que getstr() Enter .

Intenté configurar nocbreak() y es realmente perfecto, excepto que no se nocbreak() nada en la pantalla, así que no puedo ver lo que estoy escribiendo. Y establecer echo() no cambia eso.

También intenté usar timeout(0) , pero el resultado fue aún más loco y no funcionó.


Lo que debe hacer es verificar si un personaje está disponible con la función getch (). Si lo usa en modo sin retardo, el método no se bloqueará. Entonces necesitas comer los personajes hasta que encuentres un ''/ n'', añadiendo cada carácter al hilo resultante a medida que avanzas.

Alternativamente, y el método que uso, es usar la biblioteca GNU readline. Tiene soporte para el comportamiento no bloqueante , pero la documentación sobre esa sección no es tan excelente.

Incluido aquí hay un pequeño ejemplo que puede usar. Tiene un bucle de selección y usa la biblioteca GNU readline:

#include <stdio.h> #include <readline/readline.h> #include <readline/history.h> #include <stdlib.h> #include <stdbool.h> int quit = false; void rl_cb(char* line) { if (NULL==line) { quit = true; return; } if(strlen(line) > 0) add_history(line); printf("You typed:/n%s/n", line); free(line); } int main() { struct timeval to; const char *prompt = "# "; rl_callback_handler_install(prompt, (rl_vcpfunc_t*) &rl_cb); to.tv_sec = 0; to.tv_usec = 10000; while(1){ if (quit) break; select(1, NULL, NULL, NULL, &to); rl_callback_read_char(); }; rl_callback_handler_remove(); return 0; }

Compilar con:

gcc -Wall rl.c -lreadline