• 締切済み

C言語で、ioctlを使用し入力待ちつつ実行を続けたい

C言語で入力を読むときgetc関数やscanf関数を 使用することが多いのですが これらの関数を使用すると入力が完了するまで そこでプログラムの実行がストップしてしまい リアルタイムで処理できません そこでioctlを使用して ioctl(0, I_NREAD, &n) というコードを書き、入力があったかどうかを調べようと思いました ところがこの方法だとenterが入力されない限り キー入力があったと認識されないので たとえば"a"、"b"、"c"、"d"と入力してもすぐには読み込めず この入力のあとにenterを入力して はじめて文字が読めます enterが入力されなくても、入力された文字を調べるには どうしらたよいのでしょうか?

みんなの回答

回答No.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; }

winterofmeei
質問者

お礼

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

関連するQ&A

  • C言語で、文字とか入力されなくても実行を続けたい

    現在簡単なゲームをunix系のOSのC言語でつくってますが なにも入力されなくても停止せず実行を続けられる getcharのような関数はないのでしょうか? windows系のOSにはcons.hヘッダーあたりに そんな関数あったような気がするのですが。。。 普通のgetcharだと、文字が入力されるまで(enter押されるまで) そこで実行が一時中断されてしまい リアルタイムで動くプログラムができないのですが。。。

  • C言語のアルゴリズムについて

    C言語で「標準入力から英語の文章を読み込んで,文字列Ilmorが出現した行をその行番号とともに表示するプログラムを作りなさい.」とプログラムを作りたいのですが、文字列を発見するところまでは分かるのですが、その行どうやって表示すればいいのか分かりません。また、文章を読み込むのもすごくややこしく最後にエンターを二回押すなどの制限があります。(scanf) 参考になるプログラムを書いていただける方いませんか?できればC言語のアルゴリズムについて詳しく書いた本やサイトがあれば教えていただきたいです。 レベルは超入門的な本を2,3冊読んだ程度です。アルゴリズムなどにはまったく触れてなかったし、ライブラリー関数も少ししか載ってなかったので関数の本もあれば教えていただきたいです。

  • C言語の実行結果

    C言語プログラムで、scanfにした時、実行結果では入力した文字がそのまま表示されますが、その表示をパスワードみたいに*で表示サせることはできないのでしょうか?

  • C言語 if文でscanf関数

    C言語のif文でscanf関数を使って、~と入力されたら・・・(~は文字列)のようなプログラムを作りたいです。どうすれば良いでしょうか?(簡単にお願いします・・・)

  • C言語 1文字入力(Enterキーなし)

    C言語で 標準入力からの入力をEnterキーなしで受け取る方法がわかりません。 (昔やったような気がするんだけど。。readとか使ったような???) やりたいことは、下記のようなことです。 プロンプト > 実行しますか?(y or n) > と表示し、yキー or nキーの入力のみで、継続処理を行うかどうか判断する。このときエンターキーは押す必要はない。 環境は、windowsXP, cygwin + gcc (C言語) です。 よろしくお願いいたします。

  • C言語の入出力関数の違い

    C言語を勉強しています。 自分が知っている入出力を行う関数は printf scanf fprintf fscanf sprintf sscanf gets puts getc putc fgets fputs fgetc fputc なのですがそれぞれのメリット・デメリットの違いがまだあいまいです。 というかまだ上の4つくらいしかまともに使ったことがありません。 自分の考えでは、 ・上の4つは書式を指定でき、ファイルから読み込みするときなどは fgetsよりもfscanfが使いやすいと思っています。 ・スペースを読み込みたいときはscanfではなくgetsを使わなければならない。 ・システム開発でscanfを使うことは危険なのでほとんどない。 間違った考え方をしていたり、どのようなデータのときに どの関数を使うのが正しい、常識、と知っている方いらっしゃいましたら 教えてください。

  • C言語で、再帰呼び出しを使用せずに、文字列"(12 + 3) * (

    C言語で、再帰呼び出しを使用せずに、文字列"(12 + 3) * ( 3 * (4 + 5 ))"を、優先順位が低い順に二分木に入れる関数を作成したいのですが・・・。 char str[15] = ""(12 + 3) * ( 3 * (4 + 5 ))";なら char n[100];に n[0] = '*' n[1] = '+' n[2] = '*' n[3] = 12 n[4] = 3 n[5] = 3 n[6] = '+' n[7] = \0 n[8] = \0 n[9] = \0 n[10] = \0 n[11] = \0 n[12] = \0 n[13] = 4 n[14] = 5 (n[15] 以降は\0が格納されています。) というように入れたいのですが関数からその関数を呼び出す再帰を使わずに作成する方法がわかりません。 再帰を使用しなければかなり処理が複雑になるような気がしますがどなたか詳しい方よろしくお願いします。 言語はC言語です。

  • C++でのリアルタイム入力の方法を教えてください

    C++の入力は大体 cin>> a ; といったcinを使っていますが、これはEnterを押さなくては入力できません。 Enterを押さなくても入力が完了されるような関数があるのでしょうか。 どうか教えてください。

  • c言語について

    C言語のループのところで詰まってしまってわからないので2問ほど教えていただきたいです。 (1)nから1までの自然数を以下のように対角的に印字せよ。 Enter n:20 20 -19 --18 ---17 ・ ・ ・ ・ -----------------3 ------------------2 -------------------1 (2)入力した数に応じたピラミッドを作れ。 (i)奇数の場合 Enter:5 1 12 123 1234 12345 (ii)偶数の場合 Enter:8 1 22 333 4444 55555 666666 7777777 88888888 という問題なんですがわかるかたお願いします。

  • C言語のscanf関数についての質問です。

    閲覧ありがとうございます。 C言語についての質問です。 nと、2つのn×n行列の各成分をキーボードから入力し、 その和を計算するプログラムを作ろうとして i,j,と行列二つの配列(a[n][n]とb[n][n])をintで定義した後、 printf("行列aの成分を入力してください。\n"); for(i=0; i<=n-1; n++) {for(j=0; j<=n-1; j++) { scanf("%d",&a[i][j]); } } printf("行列bの成分を入力してください。\n"); for(i=0; i<=n-1; n++) {for(j=0; j<=n-1; j++) { scanf("%d",&b[i][j]); } } というプログラムを書いてn=3としたのですが、 「行列aの成分を入力してください」と表示されて 例えば「1 2 3 4 5 6 7 8 9」と入力してEnterキーを押しても 「行列bの成分を入力してください」という文が表示されません。 C言語を学び始めてまもないので、 まだ基本的なところが理解できていないかもしれません。 何が原因だかわかる方、解答頂けると嬉しいです。