第一:代码实现:
//Linux系统售票方法 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <pthread.h> typedef struct { char menu_choice; //菜单选择 int stand_ticket; //站票数 int seat_ticket; //坐票数 FILE *fp; //指向存储用户账号密码的文件 int userLogin[2]; //用户登录帐号和密码 int user_stand; //用户站票数 int user_seat; //用户坐票数 }STR; pthread_mutex_t lock; //互斥锁 void *menu(void *arg);//菜单线程 void *sale(void *arg);//售票线程 void *refund(void *arg);//退票线程 void *login(void *arg);//登录线程 void *enroll(void *arg);//注册线程 int main(int argc,const char *argv[]) { STR arg = { 0, 5, 5, NULL, {0}, 0, 0 };//参数包 int i; pthread_t tid[5];//线程号数组 pthread_mutex_t lock;//互斥锁 int ret; FILE *temp_p; char t[20] = {0}; char ch; if((arg.fp = fopen("id_password.txt","a+b")) == NULL) { fprintf(stderr,"open file failed\r\n"); exit(EXIT_FAILURE); } //互斥锁创建 pthread_mutex_init(&lock,NULL); //线程创建 pthread_create(&tid[0],NULL,menu,(void *)&arg); //创建菜单线程 pthread_create(&tid[1],NULL,sale,(void *)&arg); //创建售票线程 pthread_create(&tid[2],NULL,refund,(void *)&arg); //创建退票线程 pthread_create(&tid[3],NULL,login,(void *)&arg); //创建登录线程 pthread_create(&tid[4],NULL,enroll,(void *)&arg); //创建注册线程 //等待线程结束 for(i = 0;i < 5;i++) { pthread_join(tid[i],NULL); } if(arg.userLogin[0] != 0) { if((temp_p = fopen("temp.txt","w+b")) == NULL) { fprintf(stderr,"open file failed\r\n"); exit(EXIT_FAILURE); } fprintf(temp_p,"%d %d %d %d\r\n",arg.userLogin[0],arg.userLogin[1],arg.user_seat,arg.user_stand); rewind(arg.fp); while(!feof(arg.fp)) { fgets(t,20,arg.fp); sscanf(t," %d",&i); if(i != arg.userLogin[0]) { fputs(t,temp_p); } } rewind(temp_p); fclose(arg.fp); if((arg.fp = fopen("id_password.txt","w+b")) == NULL) { fprintf(stderr,"open file failed\r\n"); exit(EXIT_FAILURE); } while((ch = fgetc(temp_p))!=EOF) { fputc(ch,arg.fp); } fclose(temp_p); } fclose(arg.fp); pthread_exit(NULL); exit(EXIT_SUCCESS); return 0; } void *menu(void *arg)//菜单线程 { usleep(10);//挂起(每个线程刚开始都需要挂起,根据挂起时间不同决定哪个线程先运行) STR *argv = (STR *)arg;//强转 int flag = 1; while(1) { pthread_mutex_lock(&lock); while(1) { if(flag) { system("clear"); flag = 0; } printf("******************主菜单*************************\n" " (a) 登录账户\t(b) 注册账户\n" " (c) 购票\t(d) 退票\n" " (q) 退出\n" "**********************************************\n\n" "请输入选项:"); scanf(" %c",&argv->menu_choice); if((argv->menu_choice < 'a'|| argv->menu_choice > 'd')&& argv->menu_choice != 'q') { printf("请输入 a - d 或者 q\n"); continue; } if(argv->userLogin[0] == 0 && argv->menu_choice != 'q' && argv->menu_choice != 'a' && argv->menu_choice != 'b') { printf("请先登录或注册账户!\r\n"); continue; } break; } pthread_mutex_unlock(&lock);//解锁 if(argv->menu_choice == 'q') { pthread_exit(NULL); } usleep(200);//挂起 } } void *sale(void *arg)//售票线程 { usleep(200); STR *argv = (STR *)arg;//强转 while(1) { while(1) { pthread_mutex_lock(&lock); if(argv->menu_choice == 'q') { pthread_mutex_unlock(&lock);//解锁 pthread_exit(NULL); } if(argv->menu_choice == 'c') { break; } pthread_mutex_unlock(&lock);//解锁 usleep(200); } system("clear"); printf("**********************欢迎来到售票窗口*********************\n" " 总余票:%d\t 坐票:%d\t\t站票:%d\r\n" " 您的账户:\r\n" " 坐票:%d\t\t站票:%d\r\n" " (a) 购买坐票\t\t(b) 购买站票\r\n" " (q) 退出到主菜单\r\n" "**********************************************************\n\n" "请输入选项:", argv->stand_ticket+argv->seat_ticket,argv->seat_ticket,argv->stand_ticket, argv->user_seat, argv->user_stand); char choice = 0; int num = 0; while(scanf(" %c",&choice)!=1||(choice != 'a' && choice != 'b' && choice != 'q')) { printf("请输入a/b/q!\r\n"); } if(choice == 'a') { if(argv->seat_ticket == 0) { printf("坐票余票不足,请重新输入:\r\n"); continue; } printf("请输入购买坐票的数量:\r\n"); while(scanf(" %d",&num)!=1 || argv->seat_ticket-num < 0) { printf("请输入正确的数量:\r\n"); while(getchar()!='\n') { continue; } } argv->seat_ticket -= num; argv->user_seat += num; printf("购票成功\r\n"); }else if(choice == 'b') { if(argv->stand_ticket == 0) { printf("站票余票不足,请重新输入:\r\n"); continue; } printf("请输入购买站票的数量:\r\n"); while(scanf(" %d",&num)!=1 || argv->stand_ticket-num < 0) { printf("请输入正确的数量:\r\n"); while(getchar()!='\n') { continue; } } argv->stand_ticket -= num; argv->user_stand += num; printf("购票成功\r\n"); } pthread_mutex_unlock(&lock);//解锁 usleep(200); } } void *refund(void *arg)//退票线程 { usleep(200); STR *argv = (STR *)arg;//强转 while(1) { while(1) { pthread_mutex_lock(&lock); if(argv->menu_choice == 'q') { pthread_mutex_unlock(&lock);//解锁 pthread_exit(NULL); } if(argv->menu_choice == 'd') { break; } pthread_mutex_unlock(&lock);//解锁 usleep(200); } system("clear"); printf("**********************欢迎来到退票窗口*********************\n" " 当前账户余票:%d\t 坐票:%d\t\t站票:%d\r\n" " (a) 退坐票\t\t(b) 退站票\r\n" " (q) 退出到主菜单\r\n" "**********************************************************\n\n" "请输入选项:", argv->user_stand+argv->user_seat,argv->user_seat, argv->user_stand); char choice = 0; int num = 0; while(scanf(" %c",&choice)!=1||(choice != 'a' && choice != 'b' && choice != 'q')) { printf("请输入a/b/q!\r\n"); } if(choice == 'a') { if(argv->user_seat == 0) { printf("您的坐票不足,请重新输入:\r\n"); continue; } printf("请输入退坐票的数量:\r\n"); while(scanf(" %d",&num)!=1 || argv->user_seat-num < 0) { printf("请输入正确的数量:\r\n"); while(getchar()!='\n') { continue; } } argv->user_seat -= num; argv->seat_ticket += num; printf("退票成功\r\n"); }else if(choice == 'b') { if(argv->user_stand == 0) { printf("您的站票不足,请重新输入:\r\n"); continue; } printf("请输入退站票的数量:\r\n"); while(scanf(" %d",&num)!=1 || argv->user_stand-num < 0) { printf("请输入正确的数量:\r\n"); while(getchar()!='\n') { continue; } } argv->user_stand -= num; argv->stand_ticket += num; printf("退票成功\r\n"); } pthread_mutex_unlock(&lock);//解锁 usleep(200); } } void *enroll(void *arg)//注册线程 { usleep(200); STR *argv = (STR *)arg;//强转 while(1) { while(1) { pthread_mutex_lock(&lock); if(argv->menu_choice == 'q') { pthread_mutex_unlock(&lock);//解锁 pthread_exit(NULL); } if(argv->menu_choice == 'b') { break; } pthread_mutex_unlock(&lock);//解锁 usleep(200); } system("clear"); printf("**********************欢迎来到注册窗口*********************\n" " 请输入注册账号(6位数字):"); int id = 0; int pwd = 0; int temp = 0; int flag = 0; while(scanf(" %d",&id)!=1 || id / 100000 == 0) { printf("请输入正确的账号(6位数字):\r\n"); while(getchar()!='\n') { continue; } } rewind(argv->fp); while(!feof(argv->fp)) { fscanf(argv->fp," %d",&temp); if(temp == id) { printf("该用户名已存在!\r\n"); flag = 1; break; } } if(!flag) { printf(" 请输入密码(6位数字):"); while(scanf(" %d",&pwd)!=1 || pwd / 100000 == 0) { printf("请输入正确的密码(6位数字):\r\n"); while(getchar()!='\n') { continue; } } fseek(argv->fp,0,SEEK_END); fprintf(argv->fp,"%d %d ",id,pwd); printf("注册成功\r\n"); } pthread_mutex_unlock(&lock);//解锁 usleep(200); } } void *login(void *arg)//登录线程 { usleep(200); STR *argv = (STR *)arg;//强转 while(1) { while(1) { pthread_mutex_lock(&lock); if(argv->menu_choice == 'q') { pthread_mutex_unlock(&lock);//解锁 pthread_exit(NULL); } if(argv->menu_choice == 'a') { break; } pthread_mutex_unlock(&lock);//解锁 usleep(200); } system("clear"); printf("**********************用户登录*********************\n" " 请输入账号:"); int id = 0; int pwd = 0; int temp = 0; int flag = 0; while(scanf(" %d",&id)!=1 || id / 100000 == 0) { printf("请输入正确的账号(6位数字):\r\n"); while(getchar()!='\n') { continue; } } rewind(argv->fp); while(!feof(argv->fp)) { fscanf(argv->fp," %d",&temp); if(temp == id) { flag = 1; break; } } if(!flag) { printf("用户名错误或不存在!\r\n"); } if(flag) { printf(" 请输入密码:"); while(scanf(" %d",&pwd)!=1 || pwd / 100000 == 0) { printf("请输入正确的密码(6位数字):\r\n"); while(getchar()!='\n') { continue; } } fscanf(argv->fp," %d",&temp); if(temp == pwd) { printf("登录成功\r\n"); argv->userLogin[0] = id; argv->userLogin[1] = pwd; for(int i = 0;i < 2;i++) { fscanf(argv->fp,"%d",&argv->user_seat); fscanf(argv->fp,"%d\n",&argv->user_stand); } }else { printf("密码错误\r\n"); } } pthread_mutex_unlock(&lock);//解锁 usleep(200); } }
第二:实验效果:
售票系统