2010-06-06 12 views
14

मैं लिनक्स कंसोल का उपयोग कर रहा हूं और मैं एक प्रोग्राम करना चाहता हूं जो ईएससी दबाए जाने तक यादृच्छिक वर्णों को आउटपुट करता है। मैं ऐसे कीबोर्ड हैंडलर कैसे बना सकता हूं?सी में लिनक्स कंसोल में दबाए गए कुंजी को कैसे संभालें?

+0

समान और/या संबंधित - [सी गैर-अवरुद्ध कीबोर्ड इनपुट] (http://stackoverflow.com/q/448944/203667) – jschmier

उत्तर

2

getch() शापित पुस्तकालय से शायद? इसके अलावा, आपको getch() को अगली कीप्रेस के लिए प्रतीक्षा न करने के लिए notimeout() का उपयोग करने की आवश्यकता होगी।

+0

आपको स्पष्ट रूप से उल्लेख करना चाहिए कि आप (एन) शाप पुस्तकालय के बारे में बात कर रहे हैं। –

+0

हां, यकीन है। अपडेट किया गया। धन्यवाद। –

+2

नोट: ncurses से getch() को उचित ncurses "स्क्रीन" प्रारंभ करने की आवश्यकता है, या यह काम नहीं करेगा। – 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); 
} 
इस कार्यक्रम यू केवल esc चार के बाद enter प्रेस करने, क्योंकि getchar() एक अवरुद्ध समारोह है की आवश्यकता होगी में

। इसके अलावा आप अपनी जरूरत के अनुसार बाल प्रक्रिया के लिए नींद का समय निकाल या घटा सकते हैं।

+1

'getchar' इनपुट के लिए इंतजार कर रहा है, इसलिए कोई भी यादृच्छिक वर्ण आउटपुट नहीं किया जाएगा जबकि' getchar' उपयोगकर्ता को [प्रवेश] दबाएगा। –

4

परिवर्तन एक कुंजी दबाने के लिए tty सेटिंग्स:

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

'आईसीआरएनएल' 'c_iflag' फ़ील्ड में नहीं जाता है, न कि 'c_lflag' फ़ील्ड? –

20

एक टर्मिनल डिवाइस के लिए लाइन अनुशासन अक्सर डिफ़ॉल्ट रूप से प्रामाणिक मोड में काम करता है। इस मोड में, टर्मिनल ड्राइवर बफर को उपयोगकर्तास्पेस तक प्रस्तुत नहीं करता है जब तक कि नई लाइन देखी न हो ( कुंजी दबाएं)।

termios संरचना में हेरफेर करने के लिए आप tcsetattr() का उपयोग करके टर्मिनल को कच्चे (गैर-कैननिकल) मोड में सेट कर सकते हैं। ECHO और ICANON झंडे साफ़ करने के क्रमशः वर्णों की प्रतिध्वनि को अक्षम करते हैं और उन्हें इनपुट कतार से सीधे संतुष्ट होने का अनुरोध होता है। और VMIN के मानों को c_cc सरणी में शून्य पर सेट करने से पढ़ने के अनुरोध के तुरंत बाद वापसी अनुरोध (fgetc()) का कारण बनता है; प्रभावी ढंग से मतदान stdin। fgetc() पर कॉल EOF पर वापस आ जाएगा यदि कोई वर्ण स्ट्रीम में उपलब्ध नहीं है।

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

नोट: यह कोड सादगी के लिए त्रुटि जांच को छोड़ देता है।

+1

ऐसा लगता है लेकिन यह हर बार पूरे बफर प्रदान करता है। इसलिए यदि मैं एक दबाता हूं तो सी दबाता है, सी दबाए जाने के बाद यह एबैब – Jackie

+0

@ जैकी शायद 'जबकि (getchar()! = EOF) करता है; '' character = fgetc (stdin) के बाद; ' –

संबंधित मुद्दे