2011-12-15 1 views
4

select()을 사용하여 STDIN에서 단일 문자 (ENTER 없음)를 입력 할 수 있기를 원합니다.C select() timeout STDIN 단일 문자 (입력 없음)

사용자가 단일 키를 누르면 사용자가 ENTER를 누르지 않고 select()이 즉시 반환됩니다.

int main(void) 
{ 
    fd_set rfds; 
    struct timeval tv; 
    int retval; 

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

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

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

    if (retval == -1) 
     perror("select()"); 
    else if (retval) 
     printf("Data is available now.\n"); 
    else 
     printf("No data within five seconds.\n"); 

    exit(EXIT_SUCCESS); 
} 

이 방법은 효과가 있지만 끝내려면 ENTER 키를 눌러야합니다. 나는 단지 사용자가 키를 치고 ENTER를 기다릴 필요가 없다.

감사합니다.

답변

3

키를 터미널에 입력하면 Enter 키를 누르기 전까지 버퍼가 유지됩니다. 즉, 프로그램과 관련하여 아무 것도 입력하지 않은 것입니다. this question을 잠시 살펴볼 수도 있습니다.

+0

기본적으로 버퍼링됩니다. 아래의 David가 말한 것처럼 버퍼링 동작을 제거해야합니다. –

1

유닉스 스타일 환경에서는 termios 기능을 사용하여 수행 할 수 있습니다.

프로그램이 입력을보기 전에 라인 편집을 허용하는 터미널 기능인 표준 모드를 ​​비활성화해야합니다. tcgetattrtcsetattr 통화에서 올 수있는 오류를 잡는

#include <termios.h> 
#include <unistd.h> 

int main(int argc, char **argv) 
{ 
    /* Declare the variables you had ... */ 
    struct termios term; 

    tcgetattr(0, &term); 
    term.c_iflag &= ~ICANON; 
    term.c_cc[VMIN] = 0; 
    term.c_cc[VTIME] = 0; 
    tcsetattr(0, TCSANOW, &term); 

    /* Now the rest of your code ... */ 
} 

는 독자들에게 운동으로 남아 있습니다.

+0

'term.c_iflag & = ~ ICANON;은'man termios' 페이지에 따라'term.c_lflag & = ~ ICANON;'이어야합니다. – origo