一个无聊的自动提款机程序---最终版——进行信号的处理
来源:互联网 发布:零基础java多长时间 编辑:程序博客网 时间:2024/04/30 17:16
/* * 自动提款机程序,他会问用户很多的yes/no的问题 * * atm.sh * * while true * do * do_a_transaction # run a program * if play_again # run our program *then * continue # if "y" loop back * fi *break # if "n" break * done * * 这个银行脚本程序将程序的各个组件组合起来 * 1.第一个称为do_a_transaction的程序,完成ATM的工作 * 2.第二个组件play_again,从用户得到回答 * * */ /* * PLAY_AGAIN.C * 功能:实现组件2 * * 对用户显示提示问题 * 接受输入 * 如果是y,返回0 * 如果是n,返回1 * */ #include <stdio.h> #include <termios.h> #include <string.h> #include <fcntl.h> #include <signal.h> #include <stdlib.h> #define ASK "Do you want another transaction" /* 最大尝试次数*/ #define TRIES 7 /*每次尝试的时间*/ #define SLEEPTIME 1 /*警告用户*/ #define BEEP putchar('\a') int get_response(char *,int); int set_crmode(); int set_nodely(); int get_ok_char(); int tty_mode(int); void ctrl_c_handler(int); /* * 这个版本的play_again改进的问题包括 * 关闭规范输入,使得程序能够在用户敲击键盘的同时得到输入的字符 * * 改进包括 忽略非法键 * * 设置超时特征 * * 关闭信号ctrl-c,并设置信号处理函数 * 关闭crtl+/ * */ int main(){ int response;void ctrl_c_handler(int);//保存tty的modetty_mode(0);//设置tty的modeset_crmode();//关闭阻塞set_nodelay();//为信号SIGINT设置信号处理函数signal(SIGINT,ctrl_c_handler);//为信号quit进行禁止signal(SIGQUIT,SIG_IGN);//获得回答response = get_response(ASK,TRIES);printf("\nresponse = %d\n",response);//恢复tty的modetty_mode(1);return response; } int get_response(char *question,int maxtries){ printf("%s(y/n)?",question);int input;fflush(stdout);while(1){sleep(SLEEPTIME);input = getchar();if((input == 'y')||(input == 'Y'))return 0;if((input == 'n')||(input == 'N'))return 1;if(maxtries-- == 0)return 2;BEEP;}//循环读取用户的输入,指导用户输入ynYN/*switch(input=getchar()){ case 'y': case 'Y':return 0; case 'n': case 'N': case EOF:return 1; // default: //printf("\ncan not understand %c,",input); //printf("Please type y or n \n"); * * 当输入sure,没有显示任何内容,他会忽略错误信息 * * */} get_ok_char(){int c;while((c=getchar())!=EOF&&strchr("yYnN",c)==NULL);return c;}set_nodelay(){int termflags;termflags = fcntl(0,F_GETFL);termflags |= O_NDELAY;fcntl(0,F_SETFL,termflags);}set_crmode(){struct termios ttystate;//读取当前的终端驱动属性tcgetattr(0,&ttystate);//修改配置//关闭缓冲ttystate.c_lflag &= ~ICANON; //关闭回显ttystate.c_lflag &= ~ECHO;//保证一次仅获得一个字符ttystate.c_cc[VMIN] == 1;//保存修改tcsetattr(0,TCSANOW,&ttystate);}tty_mode(int how){static struct termios original_mode;static int original_flags; static int stored = 0;if(how == 0){tcgetattr(0,&original_mode);original_flags = fcntl(0,F_GETFL);stored = 1;}else{ tcsetattr(0,TCSANOW,&original_mode); fcntl(0,F_SETFL,original_flags);}}void ctrl_c_handler(int sigmun){tty_mode(1);printf("\n");exit(1);}