सी

2011-06-20 18 views
8

में कीबोर्ड से इनपुट पढ़ने के लिए चयन() का उपयोग कैसे करें मैं कुंजीपटल इनपुट पढ़ने के लिए चयन() का उपयोग करने की कोशिश कर रहा हूं और मैं उसमें फंस गया हूं कि मुझे नहीं पता कि कीबोर्ड से कैसे पढ़ा जाए और फ़ाइल डिस्क्रिप्टर का उपयोग करें इसलिए। मुझे इस समस्या से निपटने के लिए एसटीडीआईएन और एसटीडीआईएन_एफएलईएनओ का उपयोग करने के लिए कहा गया है लेकिन मैं अभी भी उलझन में हूं।
मैं यह कैसे कर सकता हूं?सी

+4

अगर आप सामान्य रूप में POSIX प्रोग्रामिंग के साथ अपरिचित हैं करने के लिए एक काफी मुश्किल बात है। एक चीज़ के लिए आपको टर्मिनल मोड सेट करना होगा ताकि डिवाइस प्राप्त वर्णों को बफर न करे। – antlersoft

+1

चयन() का उपयोग करने की कोई आवश्यकता नहीं है, बशर्ते कि यह होमवर्क असाइनमेंट का हिस्सा न हो। आप बस फ्रेड कर सकते हैं (STDIN ...) या पढ़ें (STDIN_FILENO ...)। –

+2

यदि आपको पूर्ण टर्मिनल नियंत्रण (कुंजी प्रेस इत्यादि) की आवश्यकता है, तो आप टर्मिनल लाइब्रेरी जैसे ** ncurses ** (विंडोज पोर्ट भी हैं) का उपयोग करके _much_ बेहतर हो सकते हैं। –

उत्तर

5

आपका प्रश्न थोड़ा उलझन में लगता है। select() इनपुट उपलब्ध होने तक ब्लॉक करने के लिए उपयोग किया जाता है। लेकिन आप सामान्य फ़ाइल-रीडिंग फ़ंक्शंस (जैसे read, fread, fgetc इत्यादि) के साथ वास्तविक पठन करते हैं।

यहां एक त्वरित उदाहरण है। यह तब तक अवरुद्ध हो जाता है जब तक कि स्टडीन में पढ़ने के लिए कम से कम एक वर्ण उपलब्ध न हो। लेकिन निश्चित रूप से जब तक आप टर्मिनल को कुछ बेकार मोड में नहीं बदलते हैं, तब तक यह तब तक अवरुद्ध हो जाता है जब तक आप एंटर दबाते हैं, जब टाइप किए गए किसी भी अक्षर को फ़ाइल बफर (कुछ टर्मिनल बफर से) में फ़्लश किया जाता है।

#include <stdio.h> 
#include <sys/select.h> 

int main(void) { 
    fd_set s_rd, s_wr, s_ex; 
    FD_ZERO(&s_rd); 
    FD_ZERO(&s_wr); 
    FD_ZERO(&s_ex); 
    FD_SET(fileno(stdin), &s_rd); 
    select(fileno(stdin)+1, &s_rd, &s_wr, &s_ex, NULL); 
    return 0; 
} 
+0

बहुत बहुत धन्यवाद, यह वास्तव में मेरे प्रश्न को स्पष्ट करता है। – drum

1

शायद, आप "विन्डोज़" पर कीबोर्ड इनपुट को देखने का तरीका चाहते हैं? विंडोज़ पर, यह एसटीडीआईएन के लिए चयन() से परिणाम नहीं प्राप्त कर सकता है। आपको PeekConsoleInput() का उपयोग करना चाहिए। और निम्न जैसे stdin के हैंडल का उपयोग करें।

hStdin = CreateFile("CONIN$", GENERIC_READ|GENERIC_WRITE, ... 

stdin पाइप इनपुट बन सकता है। यदि हां, तो आपको कोई कीबोर्ड इनपुट नहीं मिलता है।

पीएस यदि आप विंडोज के बारे में नहीं पूछते हैं, तो क्षमा करें।

+0

विंडोज़ मेरे साथ भी नहीं हुआ था। अच्छा बचाओ: सभी कोणों को कवर करें। –

4

जैसा कि पहले से ही कहा गया था, select का उपयोग करके आप बस निगरानी कर सकते हैं उदा। यह जांचने के लिए कि इनपुट डेटा पहले से पढ़ने या नहीं के लिए उपलब्ध है या नहीं। यदि यह उपलब्ध है, तो आप उदाहरण का उपयोग कर सकते हैं fgets सुरक्षित रूप से नीचे दिखाया गया है की तरह, कुछ बफर करने के लिए इनपुट डेटा को पढ़ने के लिए:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

int main(int argc, char *argv[]) 
{ 
    fd_set rfds; 
    struct timeval tv; 
    int retval, len; 
    char buff[255] = {0}; 

    /* Watch stdin (fd 0) to see when it has input. */ 
    FD_ZERO(&rfds); 
    FD_SET(0, &rfds); 

    /* Wait up to five seconds. */ 
    tv.tv_sec = 5; 
    tv.tv_usec = 0; 

    retval = select(1, &rfds, NULL, NULL, &tv); 

    if (retval == -1){ 
     perror("select()"); 
     exit(EXIT_FAILURE); 
    } 
    else if (retval){ 
     /* FD_ISSET(0, &rfds) is true so input is available now. */ 

     /* Read data from stdin using fgets. */ 
     fgets(buff, sizeof(buff), stdin); 

     /* Remove trailing newline character from the input buffer if needed. */ 
     len = strlen(buff) - 1; 
     if (buff[len] == '\n') 
      buff[len] = '\0'; 

     printf("'%s' was read from stdin.\n", buff); 
    } 
    else 
     printf("No data within five seconds.\n");    

    exit(EXIT_SUCCESS); 
}