2010-06-06 11 views

Respuesta

2

getch() de Curses library maybe? Además, deberá usar notimeout() para indicarle a getch() que no espere la siguiente pulsación de tecla.

+0

Debe explícitamente hablar de que estamos hablando de la (N) maldice biblioteca. –

+0

Sí, claro. Actualizado. Gracias. –

+2

nota: getch() de ncurses necesita una "pantalla" de ncurses adecuada para ser inicializada, o no funcionará. – ShinTakezou

-3
#include <stdio.h> 

#include <stdlib.h> 

#include <unistd.h> 

#include <signal.h> 

char * me = "Parent"; 

void sigkill(int signum) 
{ 
    //printf("=== %s EXIT SIGNAL %d ===\n", me, signum); 
    exit(0); 
} 

main() 
{ 
    int pid = fork(); 
    signal(SIGINT, sigkill); 
    signal(SIGQUIT, sigkill); 
    signal(SIGTERM, sigkill); 
    if(pid == 0) //IF CHILD 
    { 
     int ch; 
     me = "Child"; 
     while(1) 
     { 
      ch = (rand() % 26) + 'A'; // limit range to ascii A-Z 
      printf("%c",ch); 
      fflush(stdout); // flush output buffer 
      sleep(2); // don't overwhelm 
      if (1 == getppid()) 
      { 
       printf("=== CHILD EXIT SINCE PARENT DIED ===\n"); 
       exit(0); 
      } 
     } 
     printf("==CHILD EXIT NORMAL==\n"); 
    } 
    else //PARENT PROCESS 
    { 
     int ch; 
     if((ch = getchar())==27) 
      kill(pid, SIGINT); 
     //printf("==PARENT EXIT NORMAL (ch=%d)==\n", ch); 
    } 
    return(0); 
} 

En este programa u sólo tendrá que pulsar enter después esc char, porque getchar() es una función de bloqueo. También puede eliminar o disminuir el tiempo de inactividad del proceso hijo según lo necesite.

+1

Excepto que 'getchar' espera la entrada, por lo que no se generarán caracteres aleatorios mientras' getchar' espera a que el usuario presione [enter]. –

4

cambio de los ajustes de TTY para una pulsación de tecla:

int getch(void) { 
     int c=0; 

     struct termios org_opts, new_opts; 
     int res=0; 
      //----- store old settings ----------- 
     res=tcgetattr(STDIN_FILENO, &org_opts); 
     assert(res==0); 
      //---- set new terminal parms -------- 
     memcpy(&new_opts, &org_opts, sizeof(new_opts)); 
     new_opts.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHOK | ECHONL | ECHOPRT | ECHOKE | ICRNL); 
     tcsetattr(STDIN_FILENO, TCSANOW, &new_opts); 
     c=getchar(); 
      //------ restore old settings --------- 
     res=tcsetattr(STDIN_FILENO, TCSANOW, &org_opts); 
     assert(res==0); 
     return(c); 
} 
+0

¿No 'ICRNL' entra en el campo 'c_iflag', no en el campo' c_lflag'? –

20

La disciplina de línea de un equipo terminal a menudo funciona en el modo canónico de manera predeterminada. En este modo, el controlador del terminal no presenta el búfer en el espacio de usuario hasta que se ve la nueva línea (). Se ingresa la clave).

Puede configurar el terminal en modo raw (no canónico) utilizando tcsetattr() para manipular la estructura termios. Al borrar los indicadores ECHO y ICANON, se deshabilita el eco de caracteres a medida que se escriben y hace que las solicitudes de lectura se satisfagan directamente desde la cola de entrada. Establecer los valores de VTIME y VMIN en cero en la matriz c_cc hace que la solicitud de lectura (fgetc()) vuelva inmediatamente en lugar de bloquearse; efectivamente encuestando stdin. La llamada al fgetc() devolverá EOF si un carácter no está disponible en la transmisión.

#define _XOPEN_SOURCE 700 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <termios.h> 
#include <time.h> 

int getkey() { 
    int character; 
    struct termios orig_term_attr; 
    struct termios new_term_attr; 

    /* set the terminal to raw mode */ 
    tcgetattr(fileno(stdin), &orig_term_attr); 
    memcpy(&new_term_attr, &orig_term_attr, sizeof(struct termios)); 
    new_term_attr.c_lflag &= ~(ECHO|ICANON); 
    new_term_attr.c_cc[VTIME] = 0; 
    new_term_attr.c_cc[VMIN] = 0; 
    tcsetattr(fileno(stdin), TCSANOW, &new_term_attr); 

    /* read a character from the stdin stream without blocking */ 
    /* returns EOF (-1) if no character is available */ 
    character = fgetc(stdin); 

    /* restore the original terminal attributes */ 
    tcsetattr(fileno(stdin), TCSANOW, &orig_term_attr); 

    return character; 
} 

int main() 
{ 
    int key; 

    /* initialize the random number generator */ 
    srand(time(NULL)); 

    for (;;) { 
     key = getkey(); 
     /* terminate loop on ESC (0x1B) or Ctrl-D (0x04) on STDIN */ 
     if (key == 0x1B || key == 0x04) { 
      break; 
     } 
     else { 
      /* print random ASCII character between 0x20 - 0x7F */ 
      key = (rand() % 0x7F); 
      printf("%c", ((key < 0x20) ? (key + 0x20) : key)); 
     } 
    } 

    return 0; 
}

Nota: Este código omite la comprobación de errores por simplicidad.

+1

Parece que funciona, pero también parece proporcionar todo el búfer cada vez. Entonces, si presiono aa, entonces b, luego c, después de presionar c, muestra aababc – Jackie

+0

@Jackie, tal vez haga un 'while (getchar()! = EOF);' después de 'character = fgetc (stdin);' –

Cuestiones relacionadas