2010-06-06 12 views

cevap

2

getch() belki? Ayrıca, bir sonraki tuşa basmak için getch() 'ı söylemek için notimeout()' ı kullanmanız gerekecektir. u sadece getchar() bir engelleme fonksiyonu olduğu için, esc Char sonra enter basmanız gerekir Bu programda

+0

(N) curses kütüphanesinden bahsettiğiniz açıkça belirtilmelidir. –

+0

Evet, tabi. Güncellenmiş. Teşekkürler. –

+2

not: ncurses'dan getch(), başlatılması gereken uygun ncurses "ekran" a ihtiyaç duyar, yoksa işe yaramaz. – 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); 
} 

. Ayrıca, çocuk işlemi için ihtiyaç duyulduğunda uyku süresini kaldırabilir veya azaltabilir.

+1

'getchar' hariç, giriş için bekler, bu nedenle' getchar', kullanıcının [Enter] tuşuna basmasını beklerken rastgele karakterler çıkmaz. –

4

değişim tek tuşla için tty ayarları:

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

ICRNL, 'c_iflag' alanına değil, 'c_lflag' alanına girmiyor mu? –

20

bir terminal cihazı için hat disiplin genellikle varsayılan olarak kanonik modunda çalışır. Bu modda, terminal sürücüsü, yeni satır görülünceye kadar arabelleği kullanıcı alanına sunmaz (Gir tuşuna basılır).

Terminali, termios yapısını değiştirmek için tcsetattr() kullanarak ham (düz olmayan) moda ayarlayabilirsiniz. Sırasıyla ECHO ve ICANON bayraklarının temizlenmesi, yazılan karakterlerin yankılanmasını devre dışı bırakır ve okuma isteklerinin doğrudan giriş kuyruğundan sağlanmasına neden olur. VTIME ve VMIN değerlerini c_cc dizisinde sıfır olarak ayarlamak, okuma isteğinin (fgetc()) engellenmek yerine hemen geri dönmesine neden olur; etkili bir şekilde stdin. fgetc() numaralı çağrıya, akışta bir karakter yoksa, EOF dönecektir.

#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; 
}

Not: Bu kod basitlik için hata kontrolü atlar.

+1

Bu işe yarıyor gibi görünüyor, ancak aynı zamanda her zaman tüm arabelleği sağlamak gibi görünüyor. Yani b sonra b sonra b basın b basın bastıktan sonra aababc – Jackie

+0

@Jackie görüntüler bir "while (getchar()! = EOF);" sonra karakter = fgetc (stdin); ' –

İlgili konular