- ベストアンサー
入力を待たずにstdinの監視をしたい(C言語)
- C言語でstdinに入力を待たずに監視する方法を知りたいです。
- fgetc(stdin)を使用すると毎回入力を待つことになりますが、待たずに回る方法が知りたいです。
- 具体的なプログラム例として、gnuplotを使用してsinカーブを表示するプログラムにおいて、qを入力したら停止する方法を知りたいです。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
#2です。 >返信ありがとうございます.自分でも動かせました.ただ内容は完全には理解していない気がします.こういうシステムの方まで操作する系のプログラムってどういう本で勉強するものなのでしょうか? >Linuxの教科書などになるのでしょうか? 今回のselectに関しては、ネットワーク通信でノンブロッキングによるTCP/IPの通信を行うときに必須でした。そのときに、参考にしたのは「UNIXネットワークプログラミング〈Vol.1〉ネットワークAPI:ソケットとXTI」です。(W・リチャード・スティーブンス著)(但し、難度は高いです) 実際に業務で使用されるプログラムを書く場合は、徹底的なエラー対応処理が求められますので、 上記の本は、非常に参考になりました。但し、作成するプログラグが業務で使用されるものでない場合は(多少のフリーズなどが大目に見てもらえるなら)もっと簡単な参考書でよいかと思います。
その他の回答 (3)
_kbhitと_getchの組み合わせでどうでしょう? _kbhitはWindows版にしかありませんが、ネットで検索したらLunux用に作っている方がいたのでそちらを用いれば使えるかと。
お礼
返信ありがとうございます.その内容についても勉強させて頂きます.
- tatsu99
- ベストアンサー率52% (391/751)
#1の方のselectを使いなさいというアドバイスに従って作りました。 あなたのプログラムに追加を行いました。 ////以下の文を追加///// ・・・・・・ ///////////////////// が追加したところです。 以下のようにして下さい。 ---------------------------------------------------------------- #include <stdio.h> #include <math.h> #include <unistd.h> //////以下の文を追加////// #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <arpa/inet.h> #include <string.h> #include <fcntl.h> #include <errno.h> int read_q(void); int SockSelect (int sd_list[],int num_sd,long u_sec,int *ready_num_sd,int r_sts[],int *error_no ); ////////////////////////// FILE *gp; #define omega (M_PI/2) #define A 1 #define N 10 int i; int j; double x, t; int main(void) { gp = popen("gnuplot", "w"); fprintf(gp, "set xrange [0:11]\n"); fprintf(gp, "set yrange [-3.5:3.5]\n"); fprintf(gp, "set xlabel \"x\"\n"); fprintf(gp, "set ylabel \"y\"\n"); char buf; for (j = 0; j < N*160; ++j) { usleep(5000); /* if((buf = fgetc(stdin)) == 'q'){ break; } */ /////以下の文を追加//////////// if (read_q() == 1) break; /////////////////////////////// fprintf(gp, "plot '-' with lines linetype 1\n"); for (i = 0; i < j+1; ++i) { t = 0.1*i; x = A*sin(omega*t); fprintf(gp, "%f\t%f\n", t/10, x); } fprintf(gp, "e\n"); } fprintf(gp, "exit\n"); fflush(gp); pclose(gp); return 0; } /////以下の処理を追加//// #define MuS (1000000L) /* MEGA uSECOND */ #define RET_OK (0) #define RET_SELECT_ERR (-2) #define RET_TIMEOUT (-1) #define SD_STS_NOT_READY (0) /* not ready for reading */ #define SD_STS_READY (1) /* ready for reading */ #define TIME_USEC_0 (0) /* Time out wait = 0 [usec] */ //qで終了(1を返す) int read_q(void) { int ret, err_cd, sd_list[10], sd_list_num, r_sts[10], r_sts_cnt; char *cp0; char in_buf[256]; sd_list[0] = 0; sd_list_num = 1; ret = SockSelect(sd_list,sd_list_num,(long) 5000,&r_sts_cnt,r_sts,&err_cd); if (ret != RET_OK) return 0; if (r_sts[0]==SD_STS_READY){ fgets(in_buf,64,stdin); if (in_buf[0] == 'q') return 1; } return 0; } //select int SockSelect ( int sd_list[], int num_sd, long u_sec, int *ready_num_sd, int r_sts[], int *error_no ) { int ret_value = RET_OK; int i; int rtni; int max_sd; int sd_num; fd_set sds, wds, eds; struct timeval timeout; *error_no = 0; *ready_num_sd = 0; FD_ZERO( &sds ); FD_ZERO( &wds ); FD_ZERO( &eds ); sd_num = num_sd; for ( i=max_sd=0; i<sd_num; i++ ) { FD_SET( sd_list[i], &sds ); if ( sd_list[i] > max_sd ) { max_sd = sd_list[i]; } } timeout.tv_sec = u_sec / MuS; timeout.tv_usec = u_sec % MuS; errno = 0; rtni = select(max_sd+1,&sds,&wds,&eds,&timeout ); if ( rtni < 0 ) { *error_no = errno; ret_value = RET_SELECT_ERR; return( ret_value ); } else if( rtni == 0 ) { ret_value = RET_TIMEOUT; for ( i=0; i<sd_num; i++ ) { r_sts[i] = SD_STS_NOT_READY; } return( ret_value ); } for ( i=*ready_num_sd=0; i<sd_num; i++ ) { if ( FD_ISSET( sd_list[i], &sds ) ) { r_sts[i] = SD_STS_READY; *ready_num_sd = *ready_num_sd +1; } else { r_sts[i] = SD_STS_NOT_READY; } } if (*ready_num_sd == 0) { ret_value = RET_TIMEOUT; } return( ret_value ); } ///////////////////////////////////////////////////////////// CentOS6.3で動作確認済です。
お礼
返信ありがとうございます.自分でも動かせました.ただ内容は完全には理解していない気がします.こういうシステムの方まで操作する系のプログラムってどういう本で勉強するものなのでしょうか? Linuxの教科書などになるのでしょうか?
- notnot
- ベストアンサー率47% (4900/10361)
そもそも、stdinだとバッファリングされるので、ファイルディスクリプタ0をチェックしてください。 Unix/Linuxだとシステムコールselect()でチェックします。
お礼
返信ありがとうございます.こういう場合はselectを使うのですね.自分でも書けるようにしっかり勉強しようと思います.
お礼
返信が大変遅くなってしまいました.本も紹介してもらえてとてもうれしいです.さっそく調べてみます.