dポイントプレゼントキャンペーン実施中!

C言語で入力を読むときgetc関数やscanf関数を
使用することが多いのですが
これらの関数を使用すると入力が完了するまで
そこでプログラムの実行がストップしてしまい
リアルタイムで処理できません
そこでioctlを使用して

ioctl(0, I_NREAD, &n)

というコードを書き、入力があったかどうかを調べようと思いました

ところがこの方法だとenterが入力されない限り
キー入力があったと認識されないので
たとえば"a"、"b"、"c"、"d"と入力してもすぐには読み込めず
この入力のあとにenterを入力して
はじめて文字が読めます

enterが入力されなくても、入力された文字を調べるには
どうしらたよいのでしょうか?

A 回答 (1件)

こんばんは。



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;
}
    • good
    • 0
この回答へのお礼

回答ありがとうございます
プログラムを調べてみようと思います。

enterおさないと入力が受け取れないのは
Xウィンドウのせいかもしれないと知り合いから聞きました
もし、そうならiocltだけではうまくプログラムできないそうで
今度はそっちのほうも調べてみようと思います。

お礼日時:2003/11/29 09:02

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!