#include #include #include #include #include #include #define LEN1 sizeof(PSG) #define LEN sizeof(PLA) #define FORMAT "%3d%7d%5d%7d:%2d%12s%8d:%2d%6s%8d\n" #define INFO pla_num, pla1->p_num, pla1->l_num, pla1->up_hour, pla1->up_min, pla1->addr_dst, \ pla1->down_hour, pla1->down_min, pla1->price, (pla1->l_num - pla1->buy_num) typedef struct passenger { int p_num; // 航班号 char id_num[20]; // 身份证号 char name[20]; //名字 char sex[5]; //性别 int year_born; //出生年份 char dot; //字符“.” int month_born; //出生月份 int site_num; //座位号 struct passenger *next; // 下一个乘客 } PSG; typedef struct plane { int p_num; // 航班号 int l_num; // 载客数 int up_hour; // 起飞时 int up_min; // 起飞分 char addr_dst[20]; // 降落地点 int down_hour; // 降落时 int down_min; // 降落分 char price[10]; // 单价 int buy_num; // 已订票数 struct plane *next; // 下一航班 struct PSG *first; // 第一位乘客 } PLA; PSG *psg_head = NULL, *psg_end = NULL; // 乘客信息链表头指针和尾指针 PLA *pla_head = NULL, *pla_end = NULL; // 航班信息链表头指针和尾指针 char gfirst, pfirst, gsave, psave; // 判断标志 int bflag = 0; // 订票成功标志 //采用链表形式把乘客个人信息集合和航班信息集合 分别连起来,方便进行增删改查; /* 保存乘客数据 */ void save_psg_info(void) { FILE *fd; PSG *psg1; if (0 == psave) return; if ((fd = fopen("passenger.dat","wb")) == NULL) { printf("\n无法打开文件passenger.dat!"); getch(); return; } psg1 = psg_head; while (psg1) { if (fwrite(psg1, LEN1, 1, fd) != 1) { printf("\n写入数据出错!"); fclose(fd); getch(); return; } psg1 = psg1->next; } psave = 0; fclose(fd); } //把乘客数据信息放入文件中方便在微软视窗操作系统显示 /* 保存航班数据 */ void save_pla_info(void) { FILE *fp; PLA *pla1; if (0 == gsave) return; if ((fp = fopen("airplanes.dat","wb")) == NULL) { printf("\n无法打开文件airplanes.dat!"); getch(); return; } pla1 = pla_head; while (pla1) { if (fwrite(pla1, LEN, 1, fp) != 1) { printf("\n写入数据出错!"); fclose(fp); getch(); return; } pla1 = pla1->next; } gsave = 0; fclose(fp); } //把航班数据信息放入文件中方便在微软视窗操作系统显示 void make_line(char ch, int i) { while (i--) putchar(ch); putchar('\n'); } /* 检查时间输入正确 */ void check_time(int *hour, int *min) { int i; for (i=1; i != 2; i=1) { if ((i = scanf("%d:%d", hour, min)) != 2) { printf("输入格式错误! 请以\"小时:分钟\"格式重新输入: "); fflush(stdin); continue; }//对输入小时和分钟进行判断 if (!(*hour < 24 && *hour >= 0)) { printf("小时不在正常范围! 请重新输入: "); fflush(stdin); continue; } if (!(*min < 60 && *min >= 0)) { printf("分钟不在正常范围! 请重新输入: "); fflush(stdin); continue; } return; } } //对输入时间格式和大小进行检查 /* 显示航班信息 */ void display_pla_info(void) { PLA *pla1; time_t nowtime = time(0);//获取当前时间 struct tm *timeinfo; char tmp[64]; int pla_num = 0; // 记录航班信息数目 timeinfo = localtime(&nowtime);//传递当前时间 /* 显示时间 */ system("cls"); strftime(tmp, sizeof(tmp), "现在是%z %Y-%m-%d %X %A", timeinfo); puts(tmp); pla1 = pla_head;//获取链表信息 printf("\n序号 航班号 载客数 起飞时间 降落地点 降落时间 单价 剩余票数\n"); make_line('_', 70); while (pla1) { pla_num++; printf(FORMAT, INFO); make_line('_', 70); pla1 = pla1->next; } } //通过链表来逐个显示所记录的所有航班信息 /* 删除数据 */ void delete_pla_data(void) { int num; char del_pla; PLA *pla1, *pla2; system("cls"); display_pla_info(); del_again: printf("请输入要删除的航班号(非数字键返回上层:"); fflush(stdin);//刷新缓冲区 if (!(scanf("%d", &num))) return; pla1 = pla_head; pla2 = pla1; while (pla1) { if (num == pla1->p_num) { printf("\n航班号 载客数 起飞时间 降落地点 降落时间 单价\n"); make_line('_', 50); printf("%4d%6d%7d:%2d%13s%7d:%2d%6s\n", pla1->p_num, pla1->l_num, \ pla1->up_hour, pla1->up_min, pla1->addr_dst, pla1->down_hour, pla1->down_min, pla1->price); make_line('_', 50); printf("警告!您确定要删除该航班吗? (y / n) "); fflush(stdin); del_pla = getchar(); if (del_pla != 'y' && del_pla != 'Y') return; if (pla_head == pla1) pla_head = pla1->next; else pla2->next = pla1->next; free(pla1); gsave = 1; save_pla_info(); printf("删除成功! 任意键返回\n"); getch(); return; } else { pla2 = pla1; pla1 = pla1->next; } } printf("\n未找到航班信息!\n"); goto del_again; return; } //删除链表来实现 /* 检查字符串 */ void check_string(char name[20]) { int i, flag = 0; char check[20]; for (i = 0; i < 20; i++) check[i] = 0; fflush(stdin);////刷新缓冲区 while (scanf("%s", check)) { fflush(stdin); for (i = 0; i < 20; i++) { if (check[i]<65 && check[i]>32 || check[i]<97 && check[i]>90 || check[i]<=127 && check[i]>122) { flag = 1; break; } } if (flag == 1) { for (i = 0; i < 20; i++) check[i] = 0; flag = 0; printf("\n输入出错,请重新输入: "); } else { strncpy(name, check, 20); break; } } } /* 订票处理 */ void buy_ticket(PLA *pla1) { int i; FILE *fd; PSG *psg1 = NULL; if ((fd = fopen("passenger.dat", "a+")) == NULL) { printf("打开文件passenger.dat出错!\n"); getch(); return; } psg1 = (PSG *)malloc(LEN1); if (psg1 == NULL) { printf("分配内存失败,按任意键退出!\n"); getch(); return; } system("cls"); psg1->p_num = pla1->p_num; // 航班号 psg1->site_num = pla1->buy_num; // 座位号 printf("警告:请勿恶意输入,否则将导致您订票失败!\n"); printf("请输入您的相关信息:\n"); fflush(stdin); make_line('_', 70); printf("身份证号:"); id_again: for (i = 0; i < 20; i++) psg1->id_num[i] = 0; scanf("%s", psg1->id_num); if (psg1->id_num[17]==0 || psg1->id_num[18]!=0) { printf("\n您输入的身份证号码长度有误,请检查后重新输入: "); goto id_again; } for (i = 14; i < 17; i++) { if (psg1->id_num[i]<65 && psg1->id_num[i]>57 || psg1->id_num[i]<48 || psg1->id_num[i]<97 && \ psg1->id_num[i]>90 || psg1->id_num[i]<=127 && psg1->id_num[i]>122) { printf("\n您输入的身份证号码有误,请检查后重新输入: "); goto id_again; } } for (i = 0; i < 14; i++) { if ( !(psg1->id_num[i]<='9' && psg1->id_num[i]>='0') ) { printf("\n您输入的身份证号码有误,请检查后重新输入: "); goto id_again; } } printf("姓名:"); check_string(psg1->name); printf("性别(男/女/male/female):"); sex_again: fflush(stdin); scanf("%s", psg1->sex); if (strcmp(psg1->sex, "男") && strcmp(psg1->sex, "女") && strcmp(psg1->sex, "male") && strcmp(psg1->sex, "female")) { printf("\n输入出错,请输入您的正确性别:"); goto sex_again; } printf("出生年月(如:1994-10):"); // psg1->born = (char *)malloc(8); born_again: // for (i = 0; i < 8; i++) // psg1->born[i] = 0; fflush(stdin); while (scanf("%d-%d", &psg1->year_born, &psg1->month_born) != 2) { fflush(stdin); printf("\n输入出错,请重新输入: "); } if (psg1->year_born > 2015 || psg1->year_born < 1900 || psg1->month_born > 12 || psg1->month_born < 1) { printf("\n您输入的出生年月有误,请检查后重新输入: "); goto born_again; } psg1->next = NULL; if (pla1->first == NULL) { // 指向第一个乘客 pla1->first = psg1; } else { psg_end = pla1->first; while (psg_end) { if (NULL == psg_end->next) { psg_end->next = psg1; } else { psg_end = psg_end->next; } } } if (fwrite(psg1, LEN1, 1, fd) != 1) { printf("保存信息出错!\n"); fclose(fd); getch(); return; } fclose(fd); // free(psg1->born); free(psg1); return; } /* 订票检查 */ void buy_check(PLA *pla1) { char find = 'y'; if ((pla1->l_num - pla1->buy_num) < 1) { printf("该航班乘客数已满,请预订其他航班.\n"); getch(); return; } printf("您是否需要预订该航班机票? (y / n) "); fflush(stdin); find = getchar(); if ('y' != find && 'Y' != find) { return; } buy_ticket(pla1); printf("\n信息输入完毕,您已成功预订%2d:%2d分飞往%s的%d航班,您的座位号是:%d.\n", \ pla1->up_hour, pla1->up_min, pla1->addr_dst, pla1->p_num, ++pla1->buy_num); bflag = 1; // 订票成功 gsave = 1; save_pla_info(); // 保存文件 } /* 按航班号查询 */ void search_pla_num(void) { int num; char find; PLA *pla1, *pla2; while (1) { buy_again: printf("请输入你需要预订的航班号(非数字键返回上层):"); fflush(stdin); if (!(scanf("%d", &num))) return; pla1 = pla_head; pla2 = pla1; while (pla1) { if (num == pla1->p_num) { printf("\n航班:%d的信息如下:", pla1->p_num); printf("\n航班号 载客数 起飞时间 降落地点 降落时间 单价 剩余票数\n"); make_line('_', 70); printf("%d%9d%6d:%2d%11s%7d:%2d%7s%8d\n", pla1->p_num, pla1->l_num, \ pla1->up_hour, pla1->up_min, pla1->addr_dst, pla1->down_hour, pla1->down_min, pla1->price, (pla1->l_num - pla1->buy_num)); make_line('_', 70); buy_check(pla1); make_line('_', 70); printf("继续订票请键入\"y\",其他键返回上一层菜单:"); fflush(stdin); find = getchar(); if ('y' != find && 'Y' != find) return; goto buy_again; } else { pla2 = pla1; pla1 = pla1->next; } } printf("\n未找到该航班信息!\n"); } } /* 按降落地点查询 */ void search_destination(void) { int num = 0; char dst[15]; PLA *pla1, *pla2; printf("请输入目的地:"); scanf("%s", dst); pla1 = pla_head; pla2 = pla1; while (pla1) { if (strcmp(dst, pla1->addr_dst) == 0) { /* 有多个航班有同一个降落地点时 */ if (num == 0) { // 只显示一次 printf("\n航班号 载客数 起飞时间 降落地点 降落时间 单价 剩余票数\n"); make_line('_', 70); num++; } printf("%d%9d%6d:%2d%10s%8d:%2d%7s%7d\n", pla1->p_num, pla1->l_num, pla1->up_hour, \ pla1->up_min, pla1->addr_dst, pla1->down_hour, pla1->down_min, pla1->price,\ (pla1->l_num - pla1->buy_num)); make_line('_', 70); } pla2 = pla1; pla1 = pla1->next; } if (0 == num) { printf("\n抱歉,飞往%s的航班尚未开通。\n任意键返回上层菜单. ", dst); getch(); return; } search_pla_num(); } /* 查询航班信息 */ void search(void) { char n = 1; while (n) { system("cls"); printf("\t查询航班信息\n"); make_line('_', 40); printf("\t1. 按航班号查询\n"); printf("\t2. 按降落地点\n"); printf("\t0. 返回主菜单\n"); make_line('_', 40); printf("\n请选择菜单:"); while (n) { search_again: fflush(stdin); n = getchar(); fflush(stdin); switch (n) { case '1': system("cls"); search_pla_num(); break; case '2': system("cls"); search_destination(); break; case '0': return; default: printf("错误!请重新输入: "); goto search_again; } break; } } } /* 检查所要增加的航班记录是否存在 */ int check_pla_num(PLA *pla) { int p_num, i = 0; char ch = 'c'; PLA *pla1, *pla2; while ('c' == ch) { printf("航班号:"); fflush(stdin); while (scanf("%d", &p_num) != 1) { fflush(stdin); printf("\n输入出错,请输入数字: "); } pla1 = pla_head; pla2 = pla1; while (pla1) { if (pla1->p_num == p_num) { printf("\n航班%d已存在,请重新确认!\n", pla1->p_num); make_line('_', 30); printf("\n键入“C”继续添加信息,其余键返回: "); fflush(stdin); scanf("%c", &ch); getchar(); if (ch != 'c' && ch != 'C') { return 1; } system("cls"); break; } else { pla2 = pla1; pla1 = pla1->next; } ch = 'y'; } if (pla1 == NULL) { pla->p_num = p_num; return 0; } } return 0; } /*检查价格*/ void check_price(char price[10]) { int i; while (scanf("%s", price)) { for (i = 0; i < strlen(price); i++) { if (price[i] > '9' || price[i] < '0') { fflush(stdin); printf("\n输入出错,请输入数字: "); break; } } if (i == strlen(price)) return; } } /* 修改数据 */ void modify_data(void) { int num, m, i; char mod_pla, ch='y'; PLA *pla1, *pla2; system("cls"); display_pla_info(); modify_again: printf("请输入要修改的航班号:"); scanf("%d", &num); pla1 = pla_head; pla2 = pla1; while (pla1) { if (num == pla1->p_num) { printf("\n航班号 载客数 起飞时间 降落地点 降落时间 单价\n"); make_line('_', 70); printf("%4d%6d%7d:%2d%12s%7d:%2d%7s\n", pla1->p_num, pla1->l_num, \ pla1->up_hour, pla1->up_min, pla1->addr_dst, pla1->down_hour, pla1->down_min, pla1->price); make_line('_', 70); printf("您确定要修改该航班吗? (y / n) "); fflush(stdin); mod_pla = getchar(); if ('y' != mod_pla && 'Y' != mod_pla) return; system("cls"); m = check_pla_num(pla1); // 检查所要增加的航班记录是否存在 if (m) return; printf("载客数:"); fflush(stdin); while (scanf("%d", &pla1->l_num) != 1 || pla1->l_num > 840 || pla1->l_num < 0) { fflush(stdin); printf("\n输入出错,请输入数字: "); } printf("起飞时间(24小时制):"); fflush(stdin); check_time(&pla1->up_hour, &pla1->up_min); printf("降落地点:"); check_string(pla1->addr_dst); printf("降落时间(24小时制):"); check_time(&pla1->down_hour, &pla1->down_min); printf("单价:"); fflush(stdin); check_price(pla1->price); fflush(stdin); gsave = 1; save_pla_info(); system("cls"); printf("原航班%d已成功修改为新航班%d!", num, pla1->p_num); getch(); return; } else { pla2 = pla1; pla1 = pla1->next; } } printf("\n未找到航班信息!\n输入'y' / 'Y'继续修改,其余键返回主菜单 "); fflush(stdin); // 刷新缓冲区 scanf("%c", &ch); fflush(stdin); if (ch != 'y' && ch != 'Y') return; else goto modify_again; } /* 读取乘客信息 */ void read_psg_data(void) { FILE *fd; PSG *psg1; if ((fd = fopen("passenger.dat", "rb")) == NULL) { pfirst = 1; return; } while (!feof(fd)) { psg1 = (PSG *)malloc(LEN1); // 申请一段内存 if (psg1 == NULL) { printf("分配内存失败,按任意键退出!\n"); getch(); return; } fread(psg1, LEN1, 1, fd); // 把数据读入内存中 if (feof(fd)) break; // 检查是否在文件尾 if(psg_head == NULL) { psg_head = psg1; psg_end = psg1; } else { psg_end->next = psg1; psg_end = psg1; } psg_end->next = NULL; } pfirst = 0; fclose(fd); } /* 输入航班信息 */ void add_pla_info(void) { int m = 0, i = 0, flag = 0; // m是判断标志,i是添加的信息条数 char ch = 'y'; FILE *fp; PLA *pla; system("cls"); if((fp=fopen("airplanes.dat","ab"))==NULL) { printf("打开文件airplanes.dat出错!\n"); getch(); return; } while (1) { pla = (PLA *)malloc(LEN); // 申请一段内存 if (pla == NULL) { printf("申请内存失败,按任意键退出!\n"); getch(); return; } printf("请输入第%d条航班信息:\n", ++i); m = check_pla_num(pla); // 检查所要增加的航班记录是否存在 if (m) { fclose(fp); return; } printf("载客数:"); fflush(stdin); while (scanf("%d", &pla->l_num) != 1 || pla->l_num > 840 || pla->l_num < 0) { fflush(stdin); printf("\n输入出错,请输入正确的数目: "); } printf("起飞时间(24小时制):"); fflush(stdin); check_time(&pla->up_hour, &pla->up_min); printf("降落地点:"); check_string(pla->addr_dst); printf("降落时间(24小时制):"); check_time(&pla->down_hour, &pla->down_min); printf("单价:"); fflush(stdin); check_price(pla->price); pla->next = NULL; pla->first = NULL; pla->buy_num = 0; if (pla_head == NULL) { pla_head = pla; pla_end = pla; } else { pla_end->next = pla; pla_end = pla; } if (fwrite(pla_end, LEN, 1, fp) != 1) // 将新输入的信息写入指定的磁盘文件 printf("保存信息出错!\n"); gfirst = 0; putchar('\n'); make_line('_', 70); printf("\n输入'y' / 'Y'继续添加航班信息,其余键返回 "); fflush(stdin); // 清除缓冲区 scanf("%c", &ch); fflush(stdin); if (ch != 'y' && ch != 'Y') { fclose(fp); // 关闭文件 return; } system("cls"); } } /* 读取航班信息数据 */ void read_pla_data(void) { FILE *fp; PLA *pla1; if ((fp = fopen("airplanes.dat", "rb")) == NULL) { gfirst = 1; return; } while (!feof(fp)) { pla1 = (PLA *)malloc(LEN); // 申请一段内存 if (pla1 == NULL) { printf("分配内存失败,按任意键退出!\n"); getch(); return; } fread(pla1, LEN, 1, fp); // 把数据读入内存中 pla1->first = NULL; if (feof(fp)) break; // 检查是否在文件尾 if(pla_head == NULL) { pla_head = pla1; pla_end = pla1; } else { pla_end->next = pla1; pla_end = pla1; } pla_end->next = NULL; } gfirst = 0; fclose(fp); } /*显示初始界面*/ void menu(void) { system("cls"); printf("\n\n\n"); printf("\t\t|-----------------航班信息管理系统-----------------|\n"); printf("\t\t| 1. 订票 |\n"); printf("\t\t| 2. 查看航班信息 |\n"); printf("\t\t| 3. 航班查询 |\n"); printf("\t\t| 4. 增添航班信息 |\n"); printf("\t\t| 5. 修改航班信息 |\n"); printf("\t\t| 6. 删除航班信息 |\n"); printf("\t\t| 0. 退出 |\n"); printf("\t\t|--------------------------------------------------|\n\n"); printf("\t\t请选择您需要的操作(0-6): "); } /* 功能处理 */ void manage() { char n[2] = {0, 0}; while (1) { input_agn: scanf("%s", n); // 输入功能编号 // fflush(stdin); if (n[1] != 0) { printf("\t\t输入错误!请输入数字0-6:"); goto input_agn; } switch(n[0]) { case '1': if (gfirst) { system("cls"); // 清屏 printf("该系统中暂无航班信息,请先添加航班信息!\n"); getch(); break; } display_pla_info(); search_pla_num(); break; case '2': if (gfirst) { system("cls"); printf("该系统中暂无航班信息,请先添加航班信息!\n"); getch(); break; } display_pla_info(); printf("\n显示完毕,按任意键退出!\n"); getch(); break; case '3': if (gfirst) { system("cls"); printf("该系统中暂无航班信息,请先添加航班信息!\n"); getch(); break; } search(); break; case '4': add_pla_info(); break; case '5': if (gfirst) { system("cls"); printf("该系统中暂无航班信息,请先添加航班信息!\n"); getch(); break; } modify_data(); break; case '6': if (gfirst) { system("cls"); printf("该系统中暂无航班信息,请先添加航班信息!\n"); getch(); break; } delete_pla_data(); break; case '0': system("cls"); if ( bflag ) { printf("\n\n\n\n\n\n\t\t\t祝您旅途愉快\n\n\n\t\t\t"); exit(0); } else { printf("\n\n\n\n\n\n\t\t\t欢迎再次使用\n\n\n\t\t\t"); exit(0); } exit(0); default: printf("\t\t输入错误!请输入数字0-6:"); goto input_agn; } fflush(stdin); system("cls"); menu(); } } int main(void) { pla_head = pla_end = NULL; psg_head = psg_end = NULL; gfirst = gsave = pfirst = psave = 0; printf("\n\n\n\n\n\n\t\t\t欢迎使用广工大航班信息管理系统\n"); make_line('*', 80); printf("按任意键:"); getch(); read_psg_data(); read_pla_data(); system("cls"); menu(); manage(); return 0; }