Linuxプログラミングでキーボードの値を取得する方法

このQ&Aのポイント
  • Linuxのgccでのプログラミングで、キーボードのどのキーが押されたのかを変数に代入したり取得したりする方法はありますか?
  • 永久ループを使いながら、キーボードの入力を監視し、押されたキーに応じて特定の処理を行うプログラムを作ることは可能ですか?
  • ご教授いただけると幸いです。
回答を見る
  • ベストアンサー

Linuxプログラミングで、キーボードの値がほしい

Linuxのgccでのプログラミングで、キーボードのどのキーが押されたのかを変数に代入したりして取得したりすることはできないでしょうか? 例えば、while分で永久ループを作っておいて、 while(1) { if(aのキーが押されている場合) printf("A key is pushing!") elseif(sのキーが押されている場合) printf("B key is pushing!") elseif(dのキーが押されている場合) printf("D key is pushing!") ・・・ } このようなプログラムを作ることはできないでしょうか? どうぞ、ご教授の程よろしくお願い致します。

質問者が選んだベストアンサー

  • ベストアンサー
  • wormhole
  • ベストアンサー率28% (1619/5653)
回答No.2

できますが、かなり面倒です。 termiosやncursesなんかを調べて見るといいかも。

techhouse
質問者

お礼

回答頂きありがとうございます。 #1の方に教えて頂いたプログラムをやってみたのですが、 このgetchar()関数ですが、何か文字を入力してからエンターキーが押されないと、cの変数に値が代入されないようですが、例えば1文字入れたら、自動的にエンターキーを入力するようにすることはできないでしょうか? また、数秒たったら、自動的にcに値を代入して、次のステップに自動的に進むようにするようなことはできないのでしょうか? 今回教えて頂いたncursesというのでがありますが、 http://taichino.com/programming/1925 こちらのサイトに載っている // キー入力する場合は以下 keypad(stdscr, true); wtimeout(stdscr, 100); // 100ミリ秒でgetchがタイムアウト このような関数が使えれば、エンターキーを押さなくても定期的なキーの値の取得ができると言うことなのでしょうか? すみませんが、どうぞよろしくお願い致します。

techhouse
質問者

補足

お世話になっております。 現在、Ubuntu Linuxのgccを使っており、curuses.hを試しているのですが、次のようなエラーが出てきます。 root@ubuntu:~/20140411# gcc -o test_getchar test_getchar.c test_getchar.c:3:21: fatal error: curses .h: No such file or directory #include <curses .h> ^ compilation terminated. これはどのようなエラーなのか教えて頂けませんでしょうか? curses.hというのが使えないと言うことでしょうか? どうぞ、ご教示頂きますようお願い致します。

その他の回答 (5)

  • notnot
  • ベストアンサー率47% (4846/10257)
回答No.6

簡単にはこんな感じで。 #include <stdio.h> main(){ int c; system("stty -icanon -echo"); while(1){ c = getchar(); if(c < ' ') break; /* 制御文字がキーインされたら終了 */ printf("%c key is pushed\r\n",c); } system("stty icanon echo"); }

techhouse
質問者

お礼

回答頂きありがとうございます。 実際にこの方法をやってみました。これだとエンターキーを入れる必要がないのが確かに便利なことがわかりました。ただ、何もキーが入力されないとgetchar()でペンディング状態になるのと、IO入力のようなON/OFFの使い方はできないということも実感したのですが、ちょっとしたトグル入力などはなかなか使えるような気がしました。 いまこのような感じでコードを使わせてもらってます。 http://sourceforge.jp/projects/cc1101driver/scm/svn/blobs/1971/trunk/20140411/test_getchar.c

noname#242220
noname#242220
回答No.5

基本的には割り込みプロセスなので http://sourceforge.jp/projects/linux-kernel-docs/wiki/2.3%E3%80%80ハードウェア割り込み処理 此れを改造すれば実現可能と考えます。 割り込みが発生した時にフラグを立てメインプロセスからサブプロセスにジャンプしています。 尚その際には16進データをASCIIに変換するテーブルを参照して表示しました。

techhouse
質問者

お礼

回答頂きありがとうございます。 いつかはハードウェア割り込み処理とか、カーネルとかハード制御に関わるプログラミングとかカーネルビルドも見ていきたいと思っています。いろいろと険しそうな感じはしていますががんばりたいと思います。

  • wormhole
  • ベストアンサー率28% (1619/5653)
回答No.4

>このgetchar()関数ですが、何か文字を入力してからエンターキーが押されないと、cの変数に値が代入されないようですが、例えば1文字入れたら、自動的にエンターキーを入力するようにすることはできないでしょうか? 自動でエンターキーを入力するような事はできません(私が知らないだけという可能性はあります)。 また、#3の方もおっしゃっていますがgetchar()は標準入力からの入力なので、その入力がキーボードとは限りません。 >また、数秒たったら、自動的にcに値を代入して、次のステップに自動的に進むようにするようなことはできないのでしょうか? どういう事をやりたいのかよくわかりません。 「自動的に」とはどういう事ですか? コードを書かなくてもプログラム側で勝手に判断してやって欲しいという事ですか? >このような関数が使えれば、エンターキーを押さなくても定期的なキーの値の取得ができると言うことなのでしょうか? 引用されてたヶ所は、何らかのキーが入力されていなくてもgetch()を呼び出してから100ミリ秒後にはタイムアウトして値を返すための設定ですけど(getch()はncursesが提供している関数)。 もしそれをncursesを使わずに行いたいということであれば先にもあげたtermiosを調べてみてください。 >これはどのようなエラーなのか教えて頂けませんでしょうか? メッセージに書かれていますけど? 英文読む気がない。 辞書を引きたくない。 英文読んでもわからないと諦めてる。 読んでみたが何の事かわからない。 その他。 どれでしょう? もし最初の3つのどれかなら英文読む努力くらいはしてください。 curses.h と書く所を curses .h と書いてしまってるのが原因ではあるんでしょうが。

techhouse
質問者

お礼

回答頂きありがとうございます。まだcursesやってないのですが、とりあえずという感じで擬似的なIO入力で逃げるようなことやってみました。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

標準入力はリダイレクトされている可能性があるから使えないんですよ>#1.

techhouse
質問者

お礼

回答頂きありがとうございます。リダイレクトという言葉がアルのですね。普通の使い方ではないですね。

  • maiko0318
  • ベストアンサー率21% (1483/6970)
回答No.1

http://web-ext.u-aizu.ac.jp/~jpshin/global/sccp_sods/exercise/ex03.htm #include<stdio.h> main(){ int c; /* キーボードから受け取った文字を入れておく変数 */ c = getchar(); /* キーボードから1文字だけ受け取る */ printf("c = %c \n", c); /* [%c]を使って文字を表示 */ printf("c = %d \n", c); /* [%d]を使って、文字を数値として表示できる */ } こういうのが載っていました。

techhouse
質問者

お礼

回答頂きありがとうございます。 このgetchar()関数ですが、何か文字を入力してからエンターキーが押されないと、cの変数に値が代入されないようですが、例えば1文字入れたら、自動的にエンターキーを入力するようにすることはできないでしょうか? また、数秒たったら、自動的にcに値を代入して、次のステップに自動的に進むようにするようなことはできないのでしょうか? すみませんが、どうぞよろしくお願い致します。

関連するQ&A

  • Linuxのgccでセマフォをやりたい。

    gccプログラムでマルチタスクのプログラミングをやっています。 https://sourceforge.jp/projects/cc1101driver/scm/svn/blobs/2433/trunk/20140411/main.c 以前、H8マイコンに組み込みOSを使用した際に、複数のタスクを動作させている際に、各タスクがwhile(1)で永久ループの状態をしている際に、その永久ループを一時停止するためのロック・アンロック専用のタスクを1つ作って、各タスクのロック・アンロックして動作を制御することをやったことがありました。 確かロックの場合はSempend();というので、アンロックというのはSempost();という物だったと思いました。 例えばTASK1,TASK2,TASK3という3つのタスクを作成し、それぞれを制御したい場合は、 例えばTASK1のセマフォをアンロックしたい場合は Sempost(LockTask1); このようにしたらTASK1が動作し始め、ロックしたい場合はSempend(LockTask1);というようにしたいと思います。 次の例のようなセマフォ制御をLinuxのgccのセマフォプログラミングで行うことは可能でしょうか? どうぞ、ご教示頂きますようお願い致します。 (例) //タスクセマフォ制御用タスク TASK_SEM_CTL() { while(1) { Sempost(LockTask1); delay(1000) //1sec wait Sempost(LockTask2); delay(1000) //1sec wait Sempost(LockTask3); delay(1000) //1sec wait } } TASK1 { while(1) { Sempend(LockTask1); printf("TASK1_done"); Sempost(LockTask1); } } TASK2 { while(1) { Sempend(LockTask2); printf("TASK2_done"); Sempost(LockTask2); } } TASK3 { while(1) { Sempend(LockTask3); printf("TASK3_done"); Sempost(LockTask3); } }

  • C言語でのプログラミング

    C言語でのプログラミング プログラミングの勉強中で少し疑問が出てきたので、教えていただけるとありがたいです。 1から10までの数を足していくという次のプログラミングについてです。 #include <stdio.h> void main(void) {    int a = 0, i;    for (i=1; i<=10; i++) {      a = a + i;    }    printf("1から10の合計は%dです¥n", a); } 変数として、aとiを定め、aには0が代入されています。 つぎにforループが発動する際に、iに1が代入されiが10以下であるため、a = a + iが実行されます。 このとき、右辺が先に実行されa = 1となるはずです。 ここで疑問なのですが、aには1だけ入っているのでしょうか? それとも0と1が入っているのでしょうか? そしてa = a + iが実行されたのち、i++によりiには2も入ることになると思います。 ここでも同じ疑問として、iには1と2が入っているのか? それとも2だけが入っているのか良く分かりません。 もし仮にaにもiにも数字がどんどん格納されていくのなら、なぜ足し算の式において一つの値だけを取り出して足し算を実行できるのか分かりません。 長くなりましたが、ご解答よろしくお願いします。

  • 関数の値(scanf)

    初心者なもので、言葉の使い方を間違っていたら申し訳ありません。いいたいことが伝わればよいのですが…。 scanfに関して疑問に思ったことがあります。経験的なことなので、正しいかわからないです。次の(1)と(2)から(3)のことが正しいか教えてください。 (1) int a; do{ printf("整数を入力してください\n"); }while(scanf("%d",&a) ==0); printf("入力した数は、%dです",a) このとき、「(いかなる整数)+(ENTER)」を入力しても、do~whileのループを抜け出す。 (2)また、上のプログラムで、継続条件式の中身を  … }while(scanf("%d",&a)!=0);  … とすると、「(いかなる整数)+(ENTER)」を入力してもループが抜け出せない。 (3)したがって(1)と(2)から、scanf()は入力するだけで、値を真(1)を返す。

  • プログラミング

    プログラミング初心者なのですが、次のソースについて説明お願いします。 #include<stdio.h> int main(void) { int a[3]; int i; for(i = 0; i <= 2; i++) { a[i] = i + 1; printf("a[%d] = %d\n", i a[i]); } return 0; } for文でiに0を代入して繰り返す条件を仮定したあとの a[i] = i + 1; とprintfの中の仕組みがよくわかりません・・・。 お願いします<(_ _)>

  • プログラミング合っているか教えて下さい。

    5つの整数をキーボードから入力し、合計値と平均値を出すプログラミングです。 (1)キーボードからの数値入力は「Enter 1st=○」のように表記。 (2)平均値は小数第二位まで表示。 (3)ループ文を使用する事。 #include<stidio.h> main() { int a sum=0; printf("データを5つ入力せよ\n"); scanf( %d",&a); switch(a) { case 1: printf("Enter 1st=%d",a); break; case 2: printf("Enter 2nd=%d",a); break; case 3: printf("Enter 3rd=%d",a); break; case 4: printf("Enter 4th=%d",a); break;   case 5: printf("Entre 5th=%d,a); break; } for (i=1;i<5;i++) {scanf("%d",&a; sum=sum+a;} printf("5つの合計値=%d",sum); printf("5つの平均値=%4.2f",(float)sum/5); } まだ初心者で勉強中のため、文法がおかしいかもしれませんが間違い等のご指摘、宜しくお願いします。

  • プログラミング教えてください!!!お願いします。

    プログラミング教えてください!!!お願いします。 次の文が実行されると何がどのようにプリントされるか。何もプリントされない時は「なし」と記せ。 また、途中に「ブランク」が入る場合は、”b”と記せ。 (1) int func1(), func2(); int data = 100; main() { int w = 1; static x =10; printf("** %d, %d, %d\n" ,w,x,data); func1(); printf("** %d, %d, %d\n" ,w,x,data); } int func1(){ int w = 2; static int x = 20: printf("*** %d, %d, %d\n", w, x, data); x += 10; func2(); printf("*** %d, %d, %d\n" , w,x,data); x *= 2; data = data - x; } int func2() { int w = 3; static int x = 30; printf("**** %d, %d, %d\n" ,w,x,data); data -= x; } (2) int func1(char *, char *, char *); int func2(char *, char *, char *); main() { char sta[20], stb[20], stc[20], std[20]; int i=0; func1("abc","xyz",sta); printf("%d -- %s\n" ,++i,sta); func1("123","456",stb); printf("%d -- %s\n" ,++i,stb); func1(sta,stb,stc); printf("%d -- %s\n" ,++i,stc); func2(sta,stb,std); printf("%d -- %s\n" ,++i,std); } int func1(char *a, char *b, char *c){ while(*a) *c++ = *a++; while(*b) *c++ = *b++; * c = 0x00; } int func2(char *a, char *b, char *c){ int i = 0; while(*b){ if(i%2 == 0) *c++ = *a++; else *c++ = *b++; i++; } *c = 0x00; }

  • 整数と文字を同時に扱う

    数字を入力して,正ならplusを負ならminusを、 0ならzeroを表示し、ピリオド「.」が入力されたとき プログラムを終了するプログラムを作らなければならないのですが、 整数と文字を同時に扱うのって可能ですか?? 一応、 #include<stdio.h> int main(void){ int a; while (a!='.'){ printf("変数aに数字を入力してください\n"); printf("a="); scanf("%d",&a); if(a>0){ printf("%d is plus\n",a); }else if(a==0){ printf("%d is zero\n",a); }else{ printf("%d is minus\n",a); } } return(0); } で作ったのですが、数字以外を入力すると無限ループします。

  • [Excel VBA] 行の値を1つの変数に代入したい

    たとえばA1:A10に値があったら、3個ずつ値を1つの変数に代入したいのですがそのようなことは可能でしょうか?(改行は"%0D%0A"に置換します) たとえば、A1:A10に A B C D E F G H I J K とあったら、 1ループ目: strString = "A%0D%0AB%0D%0AC" のように代入したいのですが。 1つ1つのセルの値を追加代入していくしかないのでしょうか?

  • UWSCのプログラミングついて教えてください。

    UWSCについてです。 私は、UWSCをまだ1週間ほどしか触っていない超初心者です。 下記のようなプログラミングを組みたいと思っているので、プログラミング初挑戦なので右も左も良く分かっていません。 UWSCのプログラミングに詳しい方助けてください。 私の組みたいプログラミングは ("A.BMP",0)を無制限ループしつつ、("B.BMP",0)は2時間おきにループしつつ、("C.BMP",0)を30分間に30回実行する 場合のプログラミングです。【3つ同時進行です。】 宜しくお願いします。 while True ifb CHKIMG("A.BMP",0) x=G_IMG_X // 画像の座標をxへ代入 y=G_IMG_Y // 画像の座標をyへ代入 BTN(LEFT, CLICK, x, y, 80) endif ifb CHKIMG("B.BMP",0) x=G_IMG_X // 画像の座標をxへ代入 y=G_IMG_Y // 画像の座標をyへ代入 BTN(LEFT, CLICK, x, y, 80) endif ifb CHKIMG("C.BMP",0) x=G_IMG_X // 画像の座標をxへ代入 y=G_IMG_Y // 画像の座標をyへ代入 BTN(LEFT, CLICK, x, y, 80) endif wend

  • Cプログラミング 

    素数を判定するプログラミングの作成で以下のプログラミングを作成したのですが、すべて 素数でないとでてしまいます。どなたか間違いをおしえていただけませんでしょうか。 #include<stdio.h> int main(void) { int num,i; printf("Please input a number:"); scanf("%d",&num); for (i=2; i < num ; i++){num % i; if (num % i == 0) break; } if (num % i == 0) printf("%d is not prime. \n" ,num); else printf("%d is prime. \n" ,num); return 0; }

専門家に質問してみよう