资源描述
C语言课程设计报告
课 程 设 计
课程名称 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 -
- 35 -
一 设计目的
进一步加深、巩固所学专业课程(《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所示:
开始
输出菜单
打开文件
根据菜单输入n的值选择程序
退出
保存
删除
修改
查询
显示
输出
输入
结束
图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_end->next = pla1; 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是否成功
输入航班号
重新输入
否
是
航班记录已存在?
输入载客数
是
重新输入
否
是否数字且在正常范围
输入起飞时间
否
是
重新输入
时间格式正确?
输入降落地点
重新输入
是
否
地点格式正确?
输入降落时间
重新输入
是
否
时间格式正确?
输入单价
是
重新输入
否
是否数字?
是
否
pla_head为空?
pla_end->next = pla; pla_head = pla;
pla_end = pla; pla_end = pla;
保存新航班数据到文件
图3 输入航班数据流程图
3、 显示浏览航班信息:显示信息包括航班号、最大载客数、起飞地点、起飞时间、降落地点、降落时间、单价、剩余票数,调用了时间函数localtime()获取当前系统时间;用函数void display_pla_info(void)完成此操作。
算法:把读取文件后产生的链表按照一定的格式输出到屏幕上。N-S流程图如图4所示:
将链表头赋给航班结构体局部变量
while(未到链表尾)
printf(pla1);
pla1 = pla1->next;
图4 显示航班信息流程图
4、 删除航班信息:删除一个航班的所有信息,调用函数void delete_pla_data(void)完成是删除操作。
算法:显示所有航班信息,要求用户输入需删除的航班号,在while循环中遍历链表,找到数据则显示出来,再次要求用户确认删除,若删除,该数据的下一条数据地址将会取代当前的数据地址,即从链表中删除了,调用save_pla_info()保存新的链表;若没有找到航班则要求用户重新输入。N-S流程图如图5所示:
输入航班号
否
是
到达链表尾?
是
否
提示找不到航班,重新输入
输入的航班号与pla1_num相同?
是
否
pla2 = pla1; 输出该航班信息
否
是
pla1 = pla1->next; 确认删除?
返回菜单
删除的航班是链表头?
pla_head = pla1->next; pla2->next = pla1->next;
释放pla1;
保存文件标志位置位;
调用save_pla_info()保存新的链表;
提示删除成功;
返回菜单
图5 删除航班信息流程图
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循环中遍历链表,找到要修改的数据则显示出来,询问用户是否要订票,若订票则会进入订票函数buy_check();若不订票则返回菜单;若没有找到相应的航班信息则返回上一层菜单。N-S流程图如图7所示:
按目的地
显示菜单选择程序
按航班号
选择相应的操作
输入航班号 输入目的地
否
是
否
while(不到链表尾) while(不到链表尾)
航班号相同? 目的地相同?
是
pla2 = pla1; 显示航班信息 pla2 = pla1; 显示航班信息
否
pla1 = pla1->next; 询问是否订票 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(未到链表尾)
否
是
航班号相同?
pla2 = pla1; 显示信息
否
是
pla1 = pla1->next; 调用buy_check()检查该航班已满人数?
提示用户选择其他航班
调用buy_ticket()函数完成乘客信息的录入
(包括姓名、身份证号、性别等信息),并
对正确性进行检查,然后把信息存放到乘客
文件中。
提示订票成功并返回
提示未找到航班信息后返回菜单
8、退出系统:用户在主菜单界面时按照提示即可退出系统,调用一个exit()函数来实现。
七 调试分析
7.1 源程序及注释
/* 航班信息管理系统 */
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <conio.h>
#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");
// 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->
展开阅读全文