课 程 设 计
课程名称 C 语言课程设计 题目名称 航班信息管理系统 学生学院 物理与光电工程学院 专业班级 电子科学与技术(4)班 学 号 学生姓名 指导教师
2015 年 10 月 23 日
目 录
一 设计目的 . ............................................................................................................................. - 2 - 二 课程设计的内容 . ................................................................................................................. - 2 - 三 课程设计的要求与数据 . ..................................................................................................... - 2 - 四 课程设计应完成的工作 . ..................................................................................................... - 3 - 五 总体设计 . ............................................................................................................................. - 3 - 六 详细设计 . ............................................................................................................................. - 3 - 七 调试分析 . ............................................................................................................................. - 9 -
7.1 源程序及注释 . .............................................................................................................. - 9 - 7.2 调试与测试 . ................................................................................................................ - 30 -
7.2.1 算法调试过程中出现的问题及解决方法: .................................................. - 30 - 7.2.2 主要程序运行结果 . ......................................................................................... - 32 -
八 总结.................................................................................................................................... - 35 - 九 参考文献 . ........................................................................................................................... - 36 -
一 设计目的
进一步加深、巩固所学专业课程(《C 语言程序设计》)的基本理论知识,理论联系实际,进一步培养自己综合分析问题和解决问题的能力。掌握运用C 语言独立地编写、调试应用程序和进行其他相关设计的技能。
二 课程设计的内容
对航班信息(包括航班号、最大载客数、起飞地点、起飞时间、降落地点、降落时间、单价)和乘客信息(包括航班号、身份证号码
姓名、性别、出生年月、座位号)进行管理,包括航班信息与乘客信息的输入、输出、查询、删除、统计、退出。假设现收集到了一个机场的所有的航班信息,要求用C 语言编写一个简单的航班信息管理系统,可进行录入、查询、修改和浏览航班信息的功能;乘客提出航班号、起飞地点、起飞时间、降落地点、订票数等订票要求,根据事先保存的航班数据决定乘客能否订票。只有全部满足了乘客的订票要求并且所订航班有足够的未订座位之后才能完成订票处理,并且修改该航班的未订座位数(每个航班的未订座位数的初始值就是该航班的最大载客数),否则,订票失败,并且给出不能订票的原因。
三 课程设计的要求与数据
1、对航班信息(包括航班号、最大载客数、起飞地点、起飞时间、降落地点、降落时间、单价)和乘客信息(包括航班号、身份证号码、姓名、性别、出生年月、座位号)进行管理,包括航班信息与乘客信息的输入、输出、查询、删除、统计、退出;
2、航班信息内容较多,要求设计的管理系统能够完成以下功能:
(1)、航班信息录入功能:航班信息用文件保存,可以一次完成若干条记录的输入;
(2)、航班信息浏览功能:完成全部航班记录的显示;
(3)、查询功能:完成按航班号或按目的地查找航班记录,并显示; (4)、航班信息的修改:按航班号进行修改某个航班的信息; (5)、航班信息的删除:按航班号进行删除某个航班的信息; (6)、订票处理:按乘客的订票方式完成航班订票处理;
(7)、应提供一个界面来调节各个功能,调用界面和各个功能的操作界面应尽可能清晰美观!
四 课程设计应完成的工作
1、编写算法;
2、算法测试,并有具体的测试结果和结果分析; 3、撰写课程设计报告,内容包括:
(1) 封面扉页 (2) 设计任务书 (3) 目录
(4) 总体设计方案(包括流程图) (5) 使用说明及运行实例(包括界面) (6) 成员设计内容简介
(7) 项目源代码(注意注释的使用) (8) 指导老师评语
五 总体设计
1、功能1:航班信息的输入并对输入的内容进行错误检查; 2、功能2:航班信息的显示浏览;
3、功能3:航班信息的修改并对修改的内容进行错误检查; 4、功能4:航班信息的删除; 5、功能5:航班信息的查询;
6、功能6:乘客信息输入并对输入的内容进行错误检查; 7、功能7:订票处理检查是否还有空座位; 8、退出系统。
六 详细设计
系统的整体框图如图1所示:
图1 整体框图
1、打开存放着航班信息与乘客信息的文件:分别打开航班文件与乘客文件,存放在链表中,供后续函数调用;可用函数void read_psg_data(void)、void read_pla_data(void)来实现此操作。
这是两个无参函数,用来读取存储在文件中的信息当到达文件尾时关闭文件并退出函数,带回指向链表头的一个指针和指向链表尾的指针。
算法:fopen()函数打开文件后读取一定长度的信息存到malloc()分配的内存地址空间,声明两个全局指针pla_head和psg_head,每读取一组数据就将其地址存放在pla1节点中,并链接到之前列表的尾端。N-S 流程图如图2所示(以读
取航班信息为例) :
fp=fopen(文件)
while(不到文件尾)
malloc()分配内存pla1否分配 内存失败 返回
菜单
是
fread()读取一定长度字节数据到pla1
pla1置为NULL 否
pla_head是
pla_head = pla1; pla_end = pla1;
pla_end = pla1;
pla_end_next置为NULL
读取成功标志位置为0 关闭文件
图2 打开文件读取数据流程图
2、输入航班数据与乘客数据(以航班数据为例):输入信息包括航班号、最大载客数、起飞地点等相关信息;用函数void add_pla_info(void),函数再调用int check_pla_num(PLA *pla)、void check_time(int *hour, int *min)、void
check_string(char name[20])分别进行航班号、输入的时间、输入的地点等信息的正确性验证,从源头避免出错。
算法:打开待保存输入信息的文件,在一个while 循环里面分配内存并输入数据,对输入的数据进行正确性验证,如果出错则会提示重新输入,正确输入完一个航班后将数据保存到链表尾端并将新的航班数据写入打开的文件中。N-S 流程图如图3所示(以读取航班信息为例) :
fp=fopen(文件) while(继续输入)
否malloc()分配内存pla 是否成功
输入航班号
是航班记录已存在?
是
3、显示浏览航班信息:显示信息包括航班号、最大载客数、起飞地点、起飞时间、降落地点、降落时间、单价、剩余票数,调用了时间函数localtime()获取当前系统时间;用函数void display_pla_info(void)完成此操作。
算法:把读取文件后产生的链表按照一定的格式输出到屏幕上。N-S 流程图如图4所示:
将链表头赋给航班结构体局部变量 while(未到链表尾)
4、删除航班信息:删除一个航班的所有信息,调用函数void delete_pla_data(void)完成是删除操作。
printf(pla1); pla1 = pla1->next;
图4 显示航班信息流程图
提
示出错后返回
否 是
重
新是否数字且在正常范围 输重
输入起飞时间 入新
输入重 输入降落地点
输入载客数
是
新
输否 入重输入降落时间 新
时间格式正确? 输 入重输入单价 新
输 入 重否
新 pla_end->next = pla; pla_head = pla; 输
pla_end = pla; 入 pla_end = pla;
是
是
是 是
保存新航班数据到文件
图3 输入航班数据流程图
算法:显示所有航班信息,要求用户输入需删除的航班号,在while 循环中遍历链表,找到数据则显示出来,再次要求用户确认删除,若删除,该数据的下一条数据地址将会取代当前的数据地址,即从链表中删除了,调用save_pla_info()保存新的链表;若没有找到航班则要求用户重新输入。N-S 流程图如图5所示:
输入航班号
提
示找不到航班,重新输入
否 是 是
否 pla1_numpla2 = pla1; 输出该航班信息 pla1 = pla1->next;
返
回菜单
否
pla_head = pla1->next; pla2->next = pla1->next;
释放pla1;
保存文件标志位置位;
调用save_pla_info()保存新的链表; 提示删除成功; 返回菜单
5、修改航班信息:修改一个航班的信息,调用void modify_data(void)实现此操作。
算法:显示所有航班信息,用户输入一个航班号,在while 循环中遍历链表,找到要修改的数据则显示出来,再次要求用户确认修改,若修改,则开始输入信息;若没有找到航班则返回菜单。这里用到了添加航班时的信息检查函数。N-S 流程图如图6所示:
输入航班号
while(未到链表尾)
pla1_num 否
pla2 = pla1; 输出该航班信息 pla1 = pla1->next; 是
输入新的航班号、载客数、起飞时间、降落地点、降落
返回 时间、单价,并检查每一项的格式是否符合要求 菜单 提示修改成功
返回菜单
提示未找到该航班并返回菜单
图6 修改航班信息流程图
6、查询航班信息:查询信息时分为航班号查询与目的地查询,用户可输入航班号或目的地进行查询并订票,调用void search(void)函数,内部再调用void search_pla_num(void)和void search_destination(void)两个函数实现此操作。
算法:进入查询后显示另一个菜单要求用户选择相应的查询条件。按航班号查询时,用户输入一个航班号,在while 循环中遍历链表,找到要修改的数据则
图5
显示出来,询问用户是否要订票,若订票则会进入订票函数buy_check();若不订票则返回菜单;若没有找到相应的航班信息则返回上一层菜单。N-S 流程图如图7所示:
显示菜单选择程序
按航班号
输入航班号 while(不到链表尾)
选择相应的操作
按目的地
否
pla2 = pla1; 显示航班信息 pla1 = pla1->next; 否
执行订票流程 返
回
输入目的地
while(不到链表尾) 否
是
pla2 = pla1; 显示航班信息
pla1 = pla1->next; 进入search_pla_num()
询问是否订票
未找到相应的航班信息
未找到相应的航班信息
图7 查询航班信息流程图
7、订票处理:进入订票时,会调用search_pla_num()函数完成操作。
算法:调用display_pla_info()输出所有航班信息,然后调用search_pla_num()和buy_check()订票并完成乘客身份信息的输入与格式检验。N-S 流程图如图8所示:
display_pla_info()显示所有航班信息 提示用户输入相应的航班号 while(未到链表尾) 否
航班号相同?
显示信息
否
调用buy_ticket()函数完成乘客信息的录入 (包括姓名、身份证号、性别等信息),并 对正确性进行检查,然后把信息存放到乘客 文件中。
提示订票成功并返回
是
pla2 = pla1;
pla1 = pla1->next; 是buy_check()提示
用户选择其他航班
提示未找到航班信息后返回菜单
8、退出系统:用户在主菜单界面时按照提示即可退出系统,调用一个exit()函数来实现。
七 调试分析
7.1 源程序及注释
/* 航班信息管理系统 */ #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 = 0)) {
printf("小时不在正常范围! 请重新输入: ");
fflush(stdin);
continue;
}
if (!(*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
check[i] = 0;
fflush(stdin);
while (scanf("%s", check)) {
fflush(stdin);
for (i = 0; i
if (check[i]32 || check[i]90 || check[i]122) {
flag = 1;
break;
}
}
if (flag == 1) {
for (i = 0; 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
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
if (psg1->id_num[i]id_num[i]>57 || psg1->id_num[i]id_num[i]
psg1->id_num[i]>90 || psg1->id_num[i]
psg1->id_num[i]>122) {
printf("\n您输入的身份证号码有误,请检查后重新输入: ");
goto id_again;
}
}
for (i = 0; i
if ( !(psg1->id_num[i]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
// 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 month_born > 12 || psg1->month_born
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)
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");
// getch();
// return;
}
}
/* 按降落地点查询 */
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
if (price[i] > '9' || price[i]
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
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
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; }
7.2 调试与测试
7.2.1 算法调试过程中出现的问题及解决方法:
调试时出现该错误,是因为再次编译运行的时候没有关闭原先调试时打开的控制台界面,所以无法把最新的代码信息写入.exe 文件中。 解决办法:关闭控制台再次链接即可。
②
解决方法:把第793行的变量定义语句放在函数的第一条语句位置。
解决办法:这是出现段错误的问题,可能是数组越界了。用strncpy(name, check, 20) 替换strcpy(name, check)即可。
④
解决方法: printf("继续订票请键入"y" ,其他键返回上一层菜单:"); 里面的“" ”格式有误,改成printf("继续订票请键入\"y\",其他键返回上一层菜单:") 。
⑤
解决办法:把void buy_check(PLA pla1) 改成void buy_check(PLA *pla1),原因是形参类型定义错误。
7.2.2 主要程序运行结果
1、运行开始(如图7-1)
图7-1 系统主菜单
2、选择4增添航班信息(如图7-2)
图7-2 航班信息输入界面
3、选择2查看航班信息(如图7-3)
图7-3 查看航班信息界面
4、选择3查询航班(如图7-4)
图7-4 查询航班信息菜单
5、选择5修改航班信息(如图7-5)
图7-5 修改航班信息界面
6、选择6删除航班信息(如图7-6)
图7-6 删除航班信息
7、选择1订票(如图7-7)
图7-7 订票界面
8、选择0退出系统(如图7-8)
图7-8 退出系统界面
八 总结
经过前后半个月的c 语言课程设计,从最初的系统框图、流程图到最后的成品代码,一边看书籍一边写代码,感觉自己收获不少!
首先是:要使用链表来达到这样的功能要求,甚至操作链表完成一系列动作,很方便但不容易理解,所以在这方面我们花了很多时间看课本、看别人的例程,强化了c 语言的知识。
其次,在这次做课程设计的过程中,发现了平时很多没有注意到的问题,例如:有返回值函数和无返回值函数两者被调用时时不同的......
这次课程设计虽然花了我们不少时间,但正是这些时间,让我见识到了C 语
言的重要性。这个航班信息管理系统都是在自己的知识范围内做出来的,所以界面清晰简洁,可能不太好看,但很实用!
从这里我也得到一个体会,做一个程序或者开发一个软件,应该着重从它的后台制作入手,不能做出一个中看不中用的程序或软件。
这次的课程设计让我对C 语言的知识更加扎实了,也勾起了我深入学习C 语言的兴趣。
九 参考文献
[1]曹飞飞、高文才编著.C 语言程序开发范例宝典(第2版)[M].北京:人民邮电出版社, 2010
[2]曹飞飞、高春艳等编著.C 语言开发宝典[M].北京:机械工业出版社,2013 [3]曹衍龙、林瑞仲、徐慧编著.C 语言实例解析精粹(第二版)[M].北京:人民邮电出版社,2009
[4]谭浩强著.C 程序设计(第四版)[M].北京:清华大学出版社,2010
课 程 设 计
课程名称 C 语言课程设计 题目名称 航班信息管理系统 学生学院 物理与光电工程学院 专业班级 电子科学与技术(4)班 学 号 学生姓名 指导教师
2015 年 10 月 23 日
目 录
一 设计目的 . ............................................................................................................................. - 2 - 二 课程设计的内容 . ................................................................................................................. - 2 - 三 课程设计的要求与数据 . ..................................................................................................... - 2 - 四 课程设计应完成的工作 . ..................................................................................................... - 3 - 五 总体设计 . ............................................................................................................................. - 3 - 六 详细设计 . ............................................................................................................................. - 3 - 七 调试分析 . ............................................................................................................................. - 9 -
7.1 源程序及注释 . .............................................................................................................. - 9 - 7.2 调试与测试 . ................................................................................................................ - 30 -
7.2.1 算法调试过程中出现的问题及解决方法: .................................................. - 30 - 7.2.2 主要程序运行结果 . ......................................................................................... - 32 -
八 总结.................................................................................................................................... - 35 - 九 参考文献 . ........................................................................................................................... - 36 -
一 设计目的
进一步加深、巩固所学专业课程(《C 语言程序设计》)的基本理论知识,理论联系实际,进一步培养自己综合分析问题和解决问题的能力。掌握运用C 语言独立地编写、调试应用程序和进行其他相关设计的技能。
二 课程设计的内容
对航班信息(包括航班号、最大载客数、起飞地点、起飞时间、降落地点、降落时间、单价)和乘客信息(包括航班号、身份证号码
姓名、性别、出生年月、座位号)进行管理,包括航班信息与乘客信息的输入、输出、查询、删除、统计、退出。假设现收集到了一个机场的所有的航班信息,要求用C 语言编写一个简单的航班信息管理系统,可进行录入、查询、修改和浏览航班信息的功能;乘客提出航班号、起飞地点、起飞时间、降落地点、订票数等订票要求,根据事先保存的航班数据决定乘客能否订票。只有全部满足了乘客的订票要求并且所订航班有足够的未订座位之后才能完成订票处理,并且修改该航班的未订座位数(每个航班的未订座位数的初始值就是该航班的最大载客数),否则,订票失败,并且给出不能订票的原因。
三 课程设计的要求与数据
1、对航班信息(包括航班号、最大载客数、起飞地点、起飞时间、降落地点、降落时间、单价)和乘客信息(包括航班号、身份证号码、姓名、性别、出生年月、座位号)进行管理,包括航班信息与乘客信息的输入、输出、查询、删除、统计、退出;
2、航班信息内容较多,要求设计的管理系统能够完成以下功能:
(1)、航班信息录入功能:航班信息用文件保存,可以一次完成若干条记录的输入;
(2)、航班信息浏览功能:完成全部航班记录的显示;
(3)、查询功能:完成按航班号或按目的地查找航班记录,并显示; (4)、航班信息的修改:按航班号进行修改某个航班的信息; (5)、航班信息的删除:按航班号进行删除某个航班的信息; (6)、订票处理:按乘客的订票方式完成航班订票处理;
(7)、应提供一个界面来调节各个功能,调用界面和各个功能的操作界面应尽可能清晰美观!
四 课程设计应完成的工作
1、编写算法;
2、算法测试,并有具体的测试结果和结果分析; 3、撰写课程设计报告,内容包括:
(1) 封面扉页 (2) 设计任务书 (3) 目录
(4) 总体设计方案(包括流程图) (5) 使用说明及运行实例(包括界面) (6) 成员设计内容简介
(7) 项目源代码(注意注释的使用) (8) 指导老师评语
五 总体设计
1、功能1:航班信息的输入并对输入的内容进行错误检查; 2、功能2:航班信息的显示浏览;
3、功能3:航班信息的修改并对修改的内容进行错误检查; 4、功能4:航班信息的删除; 5、功能5:航班信息的查询;
6、功能6:乘客信息输入并对输入的内容进行错误检查; 7、功能7:订票处理检查是否还有空座位; 8、退出系统。
六 详细设计
系统的整体框图如图1所示:
图1 整体框图
1、打开存放着航班信息与乘客信息的文件:分别打开航班文件与乘客文件,存放在链表中,供后续函数调用;可用函数void read_psg_data(void)、void read_pla_data(void)来实现此操作。
这是两个无参函数,用来读取存储在文件中的信息当到达文件尾时关闭文件并退出函数,带回指向链表头的一个指针和指向链表尾的指针。
算法:fopen()函数打开文件后读取一定长度的信息存到malloc()分配的内存地址空间,声明两个全局指针pla_head和psg_head,每读取一组数据就将其地址存放在pla1节点中,并链接到之前列表的尾端。N-S 流程图如图2所示(以读
取航班信息为例) :
fp=fopen(文件)
while(不到文件尾)
malloc()分配内存pla1否分配 内存失败 返回
菜单
是
fread()读取一定长度字节数据到pla1
pla1置为NULL 否
pla_head是
pla_head = pla1; pla_end = pla1;
pla_end = pla1;
pla_end_next置为NULL
读取成功标志位置为0 关闭文件
图2 打开文件读取数据流程图
2、输入航班数据与乘客数据(以航班数据为例):输入信息包括航班号、最大载客数、起飞地点等相关信息;用函数void add_pla_info(void),函数再调用int check_pla_num(PLA *pla)、void check_time(int *hour, int *min)、void
check_string(char name[20])分别进行航班号、输入的时间、输入的地点等信息的正确性验证,从源头避免出错。
算法:打开待保存输入信息的文件,在一个while 循环里面分配内存并输入数据,对输入的数据进行正确性验证,如果出错则会提示重新输入,正确输入完一个航班后将数据保存到链表尾端并将新的航班数据写入打开的文件中。N-S 流程图如图3所示(以读取航班信息为例) :
fp=fopen(文件) while(继续输入)
否malloc()分配内存pla 是否成功
输入航班号
是航班记录已存在?
是
3、显示浏览航班信息:显示信息包括航班号、最大载客数、起飞地点、起飞时间、降落地点、降落时间、单价、剩余票数,调用了时间函数localtime()获取当前系统时间;用函数void display_pla_info(void)完成此操作。
算法:把读取文件后产生的链表按照一定的格式输出到屏幕上。N-S 流程图如图4所示:
将链表头赋给航班结构体局部变量 while(未到链表尾)
4、删除航班信息:删除一个航班的所有信息,调用函数void delete_pla_data(void)完成是删除操作。
printf(pla1); pla1 = pla1->next;
图4 显示航班信息流程图
提
示出错后返回
否 是
重
新是否数字且在正常范围 输重
输入起飞时间 入新
输入重 输入降落地点
输入载客数
是
新
输否 入重输入降落时间 新
时间格式正确? 输 入重输入单价 新
输 入 重否
新 pla_end->next = pla; pla_head = pla; 输
pla_end = pla; 入 pla_end = pla;
是
是
是 是
保存新航班数据到文件
图3 输入航班数据流程图
算法:显示所有航班信息,要求用户输入需删除的航班号,在while 循环中遍历链表,找到数据则显示出来,再次要求用户确认删除,若删除,该数据的下一条数据地址将会取代当前的数据地址,即从链表中删除了,调用save_pla_info()保存新的链表;若没有找到航班则要求用户重新输入。N-S 流程图如图5所示:
输入航班号
提
示找不到航班,重新输入
否 是 是
否 pla1_numpla2 = pla1; 输出该航班信息 pla1 = pla1->next;
返
回菜单
否
pla_head = pla1->next; pla2->next = pla1->next;
释放pla1;
保存文件标志位置位;
调用save_pla_info()保存新的链表; 提示删除成功; 返回菜单
5、修改航班信息:修改一个航班的信息,调用void modify_data(void)实现此操作。
算法:显示所有航班信息,用户输入一个航班号,在while 循环中遍历链表,找到要修改的数据则显示出来,再次要求用户确认修改,若修改,则开始输入信息;若没有找到航班则返回菜单。这里用到了添加航班时的信息检查函数。N-S 流程图如图6所示:
输入航班号
while(未到链表尾)
pla1_num 否
pla2 = pla1; 输出该航班信息 pla1 = pla1->next; 是
输入新的航班号、载客数、起飞时间、降落地点、降落
返回 时间、单价,并检查每一项的格式是否符合要求 菜单 提示修改成功
返回菜单
提示未找到该航班并返回菜单
图6 修改航班信息流程图
6、查询航班信息:查询信息时分为航班号查询与目的地查询,用户可输入航班号或目的地进行查询并订票,调用void search(void)函数,内部再调用void search_pla_num(void)和void search_destination(void)两个函数实现此操作。
算法:进入查询后显示另一个菜单要求用户选择相应的查询条件。按航班号查询时,用户输入一个航班号,在while 循环中遍历链表,找到要修改的数据则
图5
显示出来,询问用户是否要订票,若订票则会进入订票函数buy_check();若不订票则返回菜单;若没有找到相应的航班信息则返回上一层菜单。N-S 流程图如图7所示:
显示菜单选择程序
按航班号
输入航班号 while(不到链表尾)
选择相应的操作
按目的地
否
pla2 = pla1; 显示航班信息 pla1 = pla1->next; 否
执行订票流程 返
回
输入目的地
while(不到链表尾) 否
是
pla2 = pla1; 显示航班信息
pla1 = pla1->next; 进入search_pla_num()
询问是否订票
未找到相应的航班信息
未找到相应的航班信息
图7 查询航班信息流程图
7、订票处理:进入订票时,会调用search_pla_num()函数完成操作。
算法:调用display_pla_info()输出所有航班信息,然后调用search_pla_num()和buy_check()订票并完成乘客身份信息的输入与格式检验。N-S 流程图如图8所示:
display_pla_info()显示所有航班信息 提示用户输入相应的航班号 while(未到链表尾) 否
航班号相同?
显示信息
否
调用buy_ticket()函数完成乘客信息的录入 (包括姓名、身份证号、性别等信息),并 对正确性进行检查,然后把信息存放到乘客 文件中。
提示订票成功并返回
是
pla2 = pla1;
pla1 = pla1->next; 是buy_check()提示
用户选择其他航班
提示未找到航班信息后返回菜单
8、退出系统:用户在主菜单界面时按照提示即可退出系统,调用一个exit()函数来实现。
七 调试分析
7.1 源程序及注释
/* 航班信息管理系统 */ #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 = 0)) {
printf("小时不在正常范围! 请重新输入: ");
fflush(stdin);
continue;
}
if (!(*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
check[i] = 0;
fflush(stdin);
while (scanf("%s", check)) {
fflush(stdin);
for (i = 0; i
if (check[i]32 || check[i]90 || check[i]122) {
flag = 1;
break;
}
}
if (flag == 1) {
for (i = 0; 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
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
if (psg1->id_num[i]id_num[i]>57 || psg1->id_num[i]id_num[i]
psg1->id_num[i]>90 || psg1->id_num[i]
psg1->id_num[i]>122) {
printf("\n您输入的身份证号码有误,请检查后重新输入: ");
goto id_again;
}
}
for (i = 0; i
if ( !(psg1->id_num[i]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
// 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 month_born > 12 || psg1->month_born
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)
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");
// getch();
// return;
}
}
/* 按降落地点查询 */
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
if (price[i] > '9' || price[i]
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
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
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; }
7.2 调试与测试
7.2.1 算法调试过程中出现的问题及解决方法:
调试时出现该错误,是因为再次编译运行的时候没有关闭原先调试时打开的控制台界面,所以无法把最新的代码信息写入.exe 文件中。 解决办法:关闭控制台再次链接即可。
②
解决方法:把第793行的变量定义语句放在函数的第一条语句位置。
解决办法:这是出现段错误的问题,可能是数组越界了。用strncpy(name, check, 20) 替换strcpy(name, check)即可。
④
解决方法: printf("继续订票请键入"y" ,其他键返回上一层菜单:"); 里面的“" ”格式有误,改成printf("继续订票请键入\"y\",其他键返回上一层菜单:") 。
⑤
解决办法:把void buy_check(PLA pla1) 改成void buy_check(PLA *pla1),原因是形参类型定义错误。
7.2.2 主要程序运行结果
1、运行开始(如图7-1)
图7-1 系统主菜单
2、选择4增添航班信息(如图7-2)
图7-2 航班信息输入界面
3、选择2查看航班信息(如图7-3)
图7-3 查看航班信息界面
4、选择3查询航班(如图7-4)
图7-4 查询航班信息菜单
5、选择5修改航班信息(如图7-5)
图7-5 修改航班信息界面
6、选择6删除航班信息(如图7-6)
图7-6 删除航班信息
7、选择1订票(如图7-7)
图7-7 订票界面
8、选择0退出系统(如图7-8)
图7-8 退出系统界面
八 总结
经过前后半个月的c 语言课程设计,从最初的系统框图、流程图到最后的成品代码,一边看书籍一边写代码,感觉自己收获不少!
首先是:要使用链表来达到这样的功能要求,甚至操作链表完成一系列动作,很方便但不容易理解,所以在这方面我们花了很多时间看课本、看别人的例程,强化了c 语言的知识。
其次,在这次做课程设计的过程中,发现了平时很多没有注意到的问题,例如:有返回值函数和无返回值函数两者被调用时时不同的......
这次课程设计虽然花了我们不少时间,但正是这些时间,让我见识到了C 语
言的重要性。这个航班信息管理系统都是在自己的知识范围内做出来的,所以界面清晰简洁,可能不太好看,但很实用!
从这里我也得到一个体会,做一个程序或者开发一个软件,应该着重从它的后台制作入手,不能做出一个中看不中用的程序或软件。
这次的课程设计让我对C 语言的知识更加扎实了,也勾起了我深入学习C 语言的兴趣。
九 参考文献
[1]曹飞飞、高文才编著.C 语言程序开发范例宝典(第2版)[M].北京:人民邮电出版社, 2010
[2]曹飞飞、高春艳等编著.C 语言开发宝典[M].北京:机械工业出版社,2013 [3]曹衍龙、林瑞仲、徐慧编著.C 语言实例解析精粹(第二版)[M].北京:人民邮电出版社,2009
[4]谭浩强著.C 程序设计(第四版)[M].北京:清华大学出版社,2010