Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

159
Vistas
La mejor manera de monitorear la pulsación de una tecla sin detener un ciclo

Estoy escribiendo un programa en C++ para Linux. Planeo usar popen() para ejecutar otro programa. Mientras espero que termine ese programa, quiero poder detectar si el usuario presiona teclas en el teclado para saber si quiere continuar procesando sus archivos o si quiere hacer una pausa después de pclose() . Cuál es la mejor manera de lograr esto?

over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

Puede usar un hilo esperando una tecla antes de llamar a popen , llamar a popen , cancelar el hilo y verificar si se presionó alguna tecla antes de llamar a pclose .

Un ejemplo que usa C (es trivial adaptarlo a C ++), estoy omitiendo las comprobaciones de errores por brevedad:

 #define _XOPEN_SOURCE #include <stdio.h> #include <pthread.h> #include <unistd.h> void *handler(void *arg) { int *key = arg; char c; while (read(STDIN_FILENO, &c, 1)) { if (*key == 0) { *key = c; } } return NULL; } int main(void) { pthread_t thread; int key = 0; pthread_create(&thread, NULL, handler, &key); // Simulate a long read using sleep 5 // to give you enough time to press a key + enter FILE *cmd = popen("sleep 5; echo 'command finished'", "r"); char str[1024]; while (fgets(str, sizeof str, cmd)) { printf("%s", str); } pthread_cancel(thread); pthread_join(thread, NULL); if (key != 0) { printf("%c was pressed\n", key); } pclose(cmd); return 0; }

EDITAR:

Alguien sugirió en los comentarios usar select en lugar de pthread s, no veo mucha ventaja en usar select , pero aquí vamos:

select() permite esperar hasta que un descriptor de archivo (en este caso, stdin ) esté listo, se puede conectar a un tiempo de espera que especifica el intervalo que select() debe bloquear esperando que el descriptor de archivo esté listo, en este caso, ya que queremos read lo que está pendiente en stdin tan pronto como finalice popen , establecemos el tiempo de espera en 0, al final necesitamos limpiar stdin , de lo contrario, terminamos contaminando la terminal con basura si el usuario comienza a escribir pero no acierta enter, o escribe más de un dígito presionando enter.

En mi humilde opinión, los hilos son una alternativa más limpia en este caso. Mismo enfoque usando select :

 #define _XOPEN_SOURCE #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/time.h> #include <termios.h> void clear_stdin(void) { int stdin_copy = dup(STDIN_FILENO); tcdrain(stdin_copy); tcflush(stdin_copy, TCIFLUSH); close(stdin_copy); } int keypress(int state) { int key = 0; // state 0 = timeout (nothing to get) if (state == 1) { char c; if (read(STDIN_FILENO, &c, 1)) { key = c; } } clear_stdin(); return key; } int main(void) { fd_set set; FD_ZERO(&set); FD_SET(STDIN_FILENO, &set); FILE *cmd = popen("sleep 5; echo 'command finished'", "r"); char str[1024]; while (fgets(str, sizeof str, cmd)) { printf("%s", str); } struct timeval timeout; timeout.tv_sec = 0; timeout.tv_usec = 0; int state = select(FD_SETSIZE, &set, NULL, NULL, &timeout); int key = keypress(state); if (key != 0) { printf("%c was pressed\n", key); } pclose(cmd); return 0; }
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda