- 締切済み
C言語で、ioctlを使用し入力待ちつつ実行を続けたい
C言語で入力を読むときgetc関数やscanf関数を 使用することが多いのですが これらの関数を使用すると入力が完了するまで そこでプログラムの実行がストップしてしまい リアルタイムで処理できません そこでioctlを使用して ioctl(0, I_NREAD, &n) というコードを書き、入力があったかどうかを調べようと思いました ところがこの方法だとenterが入力されない限り キー入力があったと認識されないので たとえば"a"、"b"、"c"、"d"と入力してもすぐには読み込めず この入力のあとにenterを入力して はじめて文字が読めます enterが入力されなくても、入力された文字を調べるには どうしらたよいのでしょうか?
- みんなの回答 (1)
- 専門家の回答
みんなの回答
- Code_Blue_Ocean
- ベストアンサー率33% (5/15)
こんばんは。 OSもアーティテクチャもコンパイラも、わからないので、貴方の環境で動くかはわかりませんが、簡単なサンプルプログラムを作ってみました。 # 当方は Vine Linux 2.6r1(i386)で、gcc Version 2.95.3 です。 一応、コンパイルは通りますし、実行もちゃんとできるようですが、 ちゃんと見てないので、不適切な部分等があるかもしれません。 --------------------------------------------------------- /* リアルタイムにキー入力をチェックする方法(サンプル) */ #include <stdio.h> #include <sys/ioctl.h> #include <termios.h> #include <unistd.h> int main(void) { char in_char = 0; /* 入力されたキーを保持 */ char read_byte = 0; /* 読み込んだバイト数 */ struct termio tty_backup; /* 変更前の設定を保持 */ struct termio tty_change; /* 変更後の設定を保持 */ /* 最初に現在の設定を退避します */ ioctl(0, TCGETA, &tty_backup); tty_change = tty_backup; /* 設定を変更し、反映させます */ tty_change.c_lflag &= ~(ECHO | ICANON); /* エコーを止め、RAW モードへ変更 */ tty_change.c_cc[VMIN] = 0; /* 0文字入力された時点で入力を受け取る */ tty_change.c_cc[VTIME] = 1; /* 何も入力がない場合、1/10秒待つ */ ioctl(0, TCSETAF, &tty_change); /* ここで設定を反映 */ /* 無限ループにしてみる */ for(;;) { /* read(システムコール)を使って標準入力から1文字取得 */ if ((read_byte = read(0, &in_char, 1)) == '\x0a') { /* もし Enter キーが入力されたなら、ループから抜ける */ break; } /* システムコールが失敗したら、異常終了する */ else if (read_byte == -1) { /* 退避していた設定に戻す */ ioctl(0, TCSETAF, &tty_backup); /* 異常終了 */ return 1; } /* 入力された文字を出力する */ else if (in_char != 0x00) { /* 入力された文字を出力する */ printf("今、 %c(%x) が入力されました\n",in_char ,in_char); } else { printf("No Input\n"); } in_char = 0x00; } /* 退避していた設定に戻す */ ioctl(0, TCSETAF, &tty_backup); /* 正常終了 */ return 0; }
お礼
回答ありがとうございます プログラムを調べてみようと思います。 enterおさないと入力が受け取れないのは Xウィンドウのせいかもしれないと知り合いから聞きました もし、そうならiocltだけではうまくプログラムできないそうで 今度はそっちのほうも調べてみようと思います。