
A 回答 (3件)
- 最新から表示
- 回答順に表示
No.3
- 回答日時:
入力待ちなしでキーを読むにはO_NONBLOCKフラッグを
セットすればOKです。これにより、read()関数やscanf()
関数を呼び出しても、キー入力があるまでそこで
止まる(ブロックされる)ことが無くなります。
あるファイルにO_NONBLOCKをセットするには、
terra5さんが言うように、
open("/dev/tty", O_RDONLY|O_NONBLOCK);
でそのファイルをオープンします。
標準入力のように、既に開いてしまっているファイルに
対しては、
fcntl(0, F_SETFL, O_NONBLOCK);
です。
読み込みもterra5さんの通りです。
ただ、これだとリターンキーが押されるまで
入力なしとみなされます。
リターンキーを押さなくても1文字ずつ入力を
受けたい場合、もう一工夫要ります。
標準入力のターミナル属性を操作することでnon-canonical
モードにして、ターミナルのバッファリングを停止します。
詳しくは、tcgetattr(), tcsetattr(), termiosなどの
manページを見てください。
ただ、nabezo-さんの仰るようにスレッドにして、
そのスレッドを入力待ちの間ブロックしたほうが、
入力待ち以外の仕事が少ない場合は、
CPU負荷が減って良いことがあります。
(逆にそうしないとビジーウェイト状態になって、CPU
負荷が異様に上がります)
#include <stdio.h>
#include <unistd.h>
#include <termios.h>
#include <signal.h>
#include <errno.h>
static void post_proc(int);
static struct termios SavedTermAttr;
int
main(int argc, char **argv)
{
char c;
signal(SIGINT, &post_proc);
struct termios term_attr;
/* Terminal control */
/* ファイルディスクリプタ0(標準入力)
のターミナル属性を取得 */
if( tcgetattr(0, &term_attr) < 0 ){
fprintf(stderr, "Can't get terminal attributes.\n");
post_proc(-1);
}
/* 取得したターミナル属性を保存 */
SavedTermAttr = term_attr;
/* ICANON、ECHOフラッグをセット */
term_attr.c_lflag &= ~(ICANON|ECHO);
/* 入力文字列の最小読出バイト数を1に */
term_attr.c_cc[VMIN] = 1;
/* 入力待ち時間を0に */
term_attr.c_cc[VTIME] = 0;
/* 変更したターミナル属性をセット */
if( tcsetattr(0, TCSANOW, &term_attr) < 0 ){
fprintf(stderr, "Can't change terminal attributes.\n");
post_proc(-1);
}
/* NONBLOCKフラグのセット */
if( fcntl(0, F_SETFL, O_NONBLOCK) == -1 ){
fprintf(stderr, "Can't fcntl().\n");
post_proc(-1);
}
/* Main loop */
while(1){
while( read(0, &c, 1) != 1 )
if( errno != EAGAIN ){
fprintf(stderr, "EOF\n");
post_proc(0);
}
printf("%c\n", c);
}
}
void
post_proc(int sig)
{
/* 保存されたターミナル属性を復元 */
if( tcsetattr(0, TCSANOW, &SavedTermAttr) < 0 ){
fprintf(stderr, "Can't change terminal attribute.\n");
exit(-1);
}
if( sig < 0 )
exit(-1);
else
exit(0);
}
No.2
- 回答日時:
#「素人」からのコメントですが、ご了承ください。
#(cursesライブラリを使ったことがあります)
cursesライブラリに、getch()という関数があります。
キーボードからの入力待ちなどに使います。
「while文で計測させて、何かキーを押すと抜けだすような制御」
とあるので、スレッドを作成して、そのスレッドで計測させては
駄目ですか?
getch()が戻ってきて、入力されたキーをチェックして、
計測を終了させるためのキーだと判断したら、while()を
終了させてあげる条件(フラグなど)をセットするとか、、、
#「入力待ちなしでキーを読む」というのがちょっと理解できなかったので
#期待されている回答ではないかもしれませんね。
No.1
- 回答日時:
非同期モードにしてi/oすれば可能だろうと思います。
例えば,
int f=open("/dev/tty", O_RDONLY|O_NONBLOCK);
char c;
if ( read(f,&c,1) == 1 ) {
/* キー入力があった */
} else }
/* キー入力がなかったか、エラー */
}
みたいなので・・・。
コンパイルもしていないので、あとはマニュアルで(^^;
dos.hはMS-DOS用のですね。
あとは、cursesにそういう関数かマクロがあったような記憶が。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
-
プロが教える店舗&オフィスのセキュリティ対策術
中・小規模の店舗やオフィスのセキュリティセキュリティ対策について、プロにどう対策すべきか 何を注意すべきかを教えていただきました!
-
linux上でgetchを使いたい
C言語・C++・C#
-
Linuxプログラミングで、キーボードの値がほしい
C言語・C++・C#
-
入力を待たずにstdinの監視をしたい(C言語)
C言語・C++・C#
-
4
waitせずにキー入力があった場合のみ処理をさせたい(C言語)
C言語・C++・C#
-
5
C言語 1文字入力(Enterキーなし)
C言語・C++・C#
-
6
Enterキーを押されたら次の処理に移るという事をしたい。
C言語・C++・C#
-
7
INIファイルからのデータ読込みについて
C言語・C++・C#
-
8
C言語で作成したプログラムの、エコーバックをなくしたい…。
C言語・C++・C#
-
9
C言語での方向キー入力判定
C言語・C++・C#
-
10
read関数をノンブロッキングで実行する(c言語)
C言語・C++・C#
-
11
ループを途中で抜けたいのですが。
C言語・C++・C#
-
12
getchar()について 教えてください。
C言語・C++・C#
-
13
C言語で、string.h conio.hを使いたい
C言語・C++・C#
-
14
マルチスレッド間でデータ交換をする方法
C言語・C++・C#
-
15
Linuxでのスレッド間メッセージについて
C言語・C++・C#
-
16
ncursesで...
C言語・C++・C#
-
17
char*を初期化したいのですが
C言語・C++・C#
-
18
fgetsなどのときのstdinのバッファを消すには?
C言語・C++・C#
-
19
C言語で今まで表示していた画面の消すには?
C言語・C++・C#
-
20
C言語 exitの使い方
C言語・C++・C#
関連するカテゴリからQ&Aを探す
このQ&Aを見た人がよく見るQ&A
人気Q&Aランキング
-
4
*をユーザーが入力した数字の数...
-
5
ループ中でのscanfおよびcin
-
6
c言語でひらがなのしりとりをで...
-
7
getchar()について 教えてくだ...
-
8
enterでループ終了
-
9
scanfが2回使えない・・・?;
-
10
最大公約数と最小公倍数を求め...
-
11
あるキーを押したら強制終了さ...
-
12
入力値が1以下、かつ数字以外の...
-
13
プログラミングの問題です 「金...
-
14
特定の文字が入力されるまで・・・
-
15
EDITコントロールで入力できる...
-
16
VB カウントダウンタイマーの作...
-
17
数値の連続入力終了条件について
-
18
cout関数を使っているのですが...
-
19
Userformの入力順序をタブオー...
-
20
Linuxで入力待ちなしkeyread関...
おすすめ情報
公式facebook
公式twitter