2011-06-20 11 views
8

Tôi đang cố gắng sử dụng select() để đọc đầu vào bàn phím và tôi bị kẹt ở chỗ tôi không biết cách đọc từ bàn phím và sử dụng bộ mô tả tệp để làm vì thế. Tôi đã được yêu cầu sử dụng STDIN và STDIN_FILENO để tiếp cận vấn đề này nhưng tôi vẫn còn bối rối.
Tôi có thể làm như thế nào?Làm thế nào để sử dụng select() để đọc đầu vào từ bàn phím trong C

+4

Đây là một điều khá khó làm nếu bạn không quen với lập trình POSIX nói chung. Đối với một điều bạn phải thiết lập chế độ thiết bị đầu cuối để thiết bị không đệm ký tự nhận được. – antlersoft

+1

Không cần phải sử dụng select(), trừ khi tất nhiên đó là một phần của bài tập về nhà. Bạn có thể chỉ cần fread (STDIN ...) hoặc đọc (STDIN_FILENO ...). –

+2

Nếu bạn cần điều khiển thiết bị đầu cuối đầy đủ (nhấn phím vv), bạn có thể sẽ sử dụng một thư viện thiết bị đầu cuối như ** ncurses ** tốt hơn (có cả các cổng Windows). –

Trả lời

5

Câu hỏi của bạn có vẻ hơi bối rối. select() được sử dụng để chặn cho đến khi có sẵn đầu vào. Nhưng bạn thực sự đọc với các chức năng đọc tập tin thông thường (như read, fread, fgetc, v.v.).

Đây là ví dụ nhanh. Nó chặn cho đến khi stdin có ít nhất một ký tự có sẵn để đọc. Nhưng tất nhiên trừ khi bạn thay đổi thiết bị đầu cuối sang một số chế độ chưa được mở, nó sẽ chặn cho đến khi bạn nhấn enter, khi bất kỳ ký tự nào được nhập vào bộ đệm tệp (từ một số bộ đệm đầu cuối).

#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

Cảm ơn bạn rất nhiều, điều này thực sự làm rõ câu hỏi của tôi. – drum

1

Có lẽ, bạn muốn tìm cách nhập vào đầu vào bàn phím trên "WINDOWS"? Trên cửa sổ, nó không thể nhận được kết quả từ select() cho STDIN. Bạn nên sử dụng PeekConsoleInput(). Và sử dụng xử lý của stdin như sau.

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

stdin có thể trở thành đầu vào ống. nếu có, bạn không nhận được bất kỳ đầu vào bàn phím nào.

P.S. Nếu bạn không hỏi về Windows, xin lỗi nhiều.

+0

Windows thậm chí không xảy ra với tôi. Nice save: bao gồm tất cả các góc. –

4

Như đã nói, bằng cách sử dụng select bạn chỉ có thể theo dõi ví dụ: stdin để kiểm tra xem dữ liệu đầu vào đã có sẵn để đọc hay chưa. Nếu nó có sẵn, bạn có thể sử dụng ví dụ: fgets để đọc dữ liệu đầu vào một cách an toàn cho một số bộ đệm, như được hiển thị bên dưới:

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