2011-12-15 6 views
4

select()を使用して、STDINから1つのchar(ENTERなし)を入力したいと考えています。C select()timeout STDIN single char(ENTERなし)

したがって、ユーザーが1つのキーを押すと、select()はすぐに戻り、ユーザーがEnterキーを押すのを待つ必要がありません。

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

Unixスタイルの環境では、これは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

関連する問題