2011-06-20 11 views
8

キーボード入力を読み込むためにselect()を使用しようとしていますが、キーボードから読み込み、ファイル記述子を使用する方法がわかりませんそう。私はこの問題に近づくためにSTDINとSTDIN_FILENOを使うように言われましたが、私はまだ混乱しています。
どうすればいいですか?select()を使用してCキーボードの入力を読み取る方法

+4

をこれが行うにはかなりトリッキーなものです。一つは、デバイスが受信した文字をバッファしないように端末モードを設定する必要があります。 – antlersoft

+1

もちろん、宿題の一部でない限り、select()を使う必要はありません。あなたはちょうどfread(STDIN ...)またはread(STDIN_FILENO ...)することができます。 –

+2

完全なターミナルコントロール(キーの押下など)が必要な場合は、** ncurses **(Windowsポートもあります)などのターミナルライブラリを使用するほうがずっと良いでしょう。 –

答えて

5

少し混乱しています。 select()は、入力が利用可能になるまでブロックするために使用されます。しかし、通常のファイル読み取り機能(例えばreadfreadfgetcなど)で実際の読み取りを行います。

ここに簡単な例があります。 stdinに少なくとも1つの文字が読み込み可能になるまでブロックされます。もちろん、ターミナルをいくつかの未調子のモードに変更しない限り、入力した文字がファイルバッファにフラッシュされる(ある端末バッファから)ときに、Enterキーを押すまでブロックされます。

#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

"WINDOWS"のキーボード入力を覗いてみたいですか? ウィンドウでは、STDINのselect()の結果を取得できません。 PeekConsoleInput()を使用する必要があります。 stdinのハンドルは次のように使用してください。

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

stdinがパイプ入力になることがあります。そうであれば、キーボード入力はありません。

P.S.あなたがWindowsについて尋ねなければ、すみません。

+0

Windowsは私にさえ起きなかった。素敵なセーブ:すべての角度をカバーする。 –

4

すでに述べたように、selectを使用すると、たとえば入力データが既に読み込み可能かどうかを確認します。利用可能な場合は、たとえば以下に示すようfgetsが安全に、いくつかのバッファへの入力データを読むために:あなたは一般的なPOSIXプログラミングに慣れていない場合

#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); 
} 
関連する問題