您的位置:首页 > 其它

一个无聊的自动提款机程序---最终版——进行信号的处理

2011-11-29 23:51 302 查看
/*
* 自动提款机程序,他会问用户很多的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的mode
tty_mode(0);

//设置tty的mode
set_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的mode
tty_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);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐