Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

162
Views
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 answers
Answer question

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!