C++/C实习报告——基于Win32 Console App的民航订票系统
源码、演示ppt及测试结果待续…
源码、演示ppt及测试结果待续…
项目名称:民航飞机订票系统
项目组成员:
韩翼 王毅飞
完成日期:2008年8月28日
学校名称;西北大学 软件工程2班
民航订票系统允许用户自由注册、登陆,用户权限分为三种级别,分别是一般浏览用户、注册用户、民航售票员和系统管理员。
(1) 所有模块程序均使用c++/c语言编写,使用Microsoft Visual C++ 6.0编译,运行环境需Windows98操作系统或以上。
(2) 本系统采用菜单操作方法,每个菜单都有相应的帮助,用户分三种权限:一般的浏览用户,注册用户、民航机票售票员,系统管理员。 根据登陆方式,选择相应的操作方式;如果是一般的浏览用户,只能按照各种方式查看航班信息。如果是一般的注册用户,不但具有一般的浏览用户所有功能,还具有查看自己的信息和订票情况,可以网上订票、退票,修改自己的信息等;如果是民航机票售票员,可以查看数据和编辑航班信息。如果是系统管理员,他拥有管理航班的所有功能,并可创建民航机票售票员,授权用户权限等功能。登录的用户名和密码应该存储在单独的文件中,有加密算法可以进行统计,查找,排序等功能。
程序主要有3个模块,机票模块FTicket.cpp/FTicket.h,用户模块FUser.cpp/FUser.h和航班模块FLight.cpp/FLight.h。
各自有一个文件来储存各自内容(用户表 users.txt航班表 flight.txt订票信息 ticket.txt).。以链表形式在文件中存储。
航班模块实现功能有
//航班链表初始化
FlightNode* Flight::InitialFlightNode(FlightNode* head)
//输入链表从文件
FlightNode* Flight::ReCheck(FlightNode* head)
//添加航班
bool Flight::InputFlight(FlightNode* head)
//输出链表到文件
bool Flight::OutPutFlight(FlightNode* head)
//航班查询
bool Flight::FlightQuery(FlightNode* head)
//修改航班
bool Flight::UpdateFlight(FlightNode* head)
//删除航班,级联删除票务信息
bool Flight::DeleteFlight(FlightNode* head,TicketNode* thead)
//航班统计
bool Flight::FlightStat(FlightNode* head)
//订票情况统计
bool Flight::TicketQueryStat(FlightNode* head)
//热门航班统计
bool Flight::HotFlight(FlightNode* head)
//冷门航班统计
bool Flight::ColdFlight(FlightNode* head)
//打折航班统计
bool Flight::DiscountFlightStat(FlightNode* head)
其中
[//输入链表从文件]与[//输出链表到文件]为文件操作,同文件航班表flight.txt相关连,功能为欲将内存中的链表存入文件中和将文件中的链表存入内存。
[//航班链表初始化]为链表操作。功能是在内存中新建一个链表,为之后操作作准备。
[//添加航班][ //航班查询][ //修改航班]为链表操作,功能是增加链表节点,查询链表节点,与修改链表节点内容。
[//删除航班,级联删除票务信息]也为链表操作。功能为删除列表节点。同时连接函数ticket.DeleteTicket(Idtmp,thead),当删除航班时同时删除被删航班得订票信息,借此避免数据的非一致性错误。
[//航班统计] [//订票统计] [//热门航班统计][//冷门航班统计][//打折航班统计]为统计部分。[//航班统计]为累加器统计,利用累加器来统计航班数量。
[//热门航班统计]和[//冷门航班统计]首先使列表按订票排序,然后为输出排序后前十得航班。如果按升序排列,前十就是冷门航班,降序前十就是热门航班。其中冷门航班添加判断语句,当入座率都在50%以上时无冷门航班。
[//订票情况统计]与[//打折航班统计]为链表内容输出,当指定航班时输出相应航班内容。
用户模块实现功能有
//用户链表初始化
UserNode* User::InitialUserNode(UserNode* head)
//输入链表从文件
void User::ReCheck(UserNode* head)
//添加用户
bool User::RegisterUser(UserNode* head)
//输出链表到文件
bool User::OutPutUser(UserNode* head)
//用户登录
int User::CheckAdmin(UserNode* head)
//更改密码
bool User::UpdatePass(UserNode* head)
//用户授权
bool User::GrantUser(UserNode* head)
//删除用户(级联删除订票信息)
bool User::DeleteUser(UserNode* head,TicketNode* thead)
//用户列表
bool User::UserList(UserNode* head)
//用户消费查询
bool User::UserConsumption(UserNode* head)
其中
[//输入链表从文件]与[//输出链表到文件]为文件操作,同文件用户表user.txt相关连,功能为欲将内存中的链表存入文件中和将文件中的链表存入内存。
[//航班链表初始化]为链表操作。功能是在内存中新建一个链表,为之后操作作准备。
[//添加用户] [//用户列表] [ //更改密码] [//用户授权]为链表操作,功能是增加链表节点,查看链表全部节点与修改链表节点内容。其中[//添加用户]由用户本人注册来实现,[//更改密码]由用户自己来更改,需要权限较低。[//用户列表]与[//用户授权]由管理员完成。需要权限较高。
[//用户登录]对比链表节点,当用户名与密码对应上时可以进行下一步操作。由用户本人来实现。
[//删除用户(级联删除订票信息)]为链表操作。功能为删除列表节点。同时连接函数ticket.DeleteuTicket(Idtmp,thead),当删除用户时,同时删除此用户得订票信息,借此避免数据的非一致性错误。此功能也为管理员功能,需要权限为高。
[//用户消费查询] 首先使列表按消费排序,然后为输出排序后前5的用户,作为本月消费前5名输出,此功能也为管理员功能。需要权限较高。
机票模块实现功能有
//机票链表初始化
TicketNode* Ticket::InitialTicketNode(TicketNode* head)
//输入链表从文件
TicketNode* Ticket::ReCheck(TicketNode* head)
//级联删除订票信息(删除航班时)
bool Ticket::DeleteTicket(char* Idtmp,TicketNode* head)
//级联删除订票信息(删除用户时)
bool Ticket::DeleteuTicket(char* Idtmp,TicketNode* head)
//输出链表到文件
bool Ticket::OutPutTicket(TicketNode* head)
//网上订票
bool Ticket::InputTicket(TicketNode* head,UserNode* uhead,FlightNode* fhead)
//退订机票
bool Ticket::TicketQuery(TicketNode* head,UserNode* uhead,FlightNode* fhead)
//订票查询
bool Ticket::TicketStat(TicketNode* head)
其中
[//输入链表从文件]与[//输出链表到文件]为文件操作,同文件订票信息 ticket.txt相关连,功能为欲将内存中的链表存入文件中和将文件中的链表存入内存。
[//机票链表初始化]为链表操作。功能是在内存中新建一个链表,为之后操作作准备。
[//网上订票] [//退订机票]为链表操作,功能是增加链表节点与删除链表节点。[//网上订票][//退订机票]皆由用户本人进行操作。权限较低。
[//级联删除订票信息(删除航班时)][//级联删除订票信息(删除用户时)]都为级联删除的一部分,嵌套在用户模块与航班模块中,减少由于数据不一致而产生的错误。
[//订票查询] 为链表内容输出,当指定用户时输出相应用户订票内容。
排序功能FSort.cpp用函数实现。查找功能整合在各自模块中。
密码部分调用SHA1加密模块实现加密。
程序运行时首先先将用户表 user.txt航班表 flight.txt订票信息 ticket.txt这3个文件中得内容读取到内存中去,一切链表计算全在内存中,运行完成后,将新的链表存储到文件中覆盖旧的文件,达到更改数据的目的。需要注意的是关于有联系的相应项目的删除要注意级联删除相应项目,防止程序出错。
算法分析
1、冒泡排序算法
使用了C++链表形式的冒泡排序方法,具体实现方法例:
while(head->link != tail)
{
p = head;
while( p -> link ->link != tail && p ->link->link !=NULL)
{
p = p -> link;
strcpy(Id,p->Id);
strcpy(Id0,p->link->Id);
if(Id[0]>=Id0[0])
{
q = new FlightNode;
节点数据交换
delete q;
}
}
tail = p->link;
}
其中tail为尾部监视指针,类似于计数器,在首轮冒泡结束后tail会自动提前一位,确保外部循环进行到总结点数减1轮次时结束排序。结点交换方法为结点交换或是数据交换,本例中采取的是数据交换方法,形式较为繁琐,不过达到了冒泡排序的目的。
2、统计算法——直接插入排序
由于统计功能与排序有相似之处,故统计中采用了一定的排序算法,具体方法是链表的直接插入排序。
例如统计热门航班前十名的算法:
FlightNode *p,*q,*h,*t;
p=head;
q=new FlightNode;
q->link = NULL;
p=p->link;
h=new FlightNode;
strcpy(h->Id,p->Id);
strcpy(h->TicketNum,p->TicketNum);
strcpy(h->MaxNum,p->MaxNum);
h->link = q->link;
q->link=h;
// bool a=false;
while( p->link != NULL)
{
p=p->link;
t=q;
// t=t->link;
while(atoi(p->TicketNum) < atoi(t->link->TicketNum))
{ if(t->link==NULL)
goto loop;
t=t->link;
if(t->link==NULL)
break;
}
h=new FlightNode;
strcpy(h->Id,p->Id);
strcpy(h->TicketNum,p->TicketNum);
strcpy(h->MaxNum,p->MaxNum);
h->link=t->link;
t->link=h;
continue;
loop: h=new FlightNode;
strcpy(h->Id,p->Id);
strcpy(h->TicketNum,p->TicketNum);
strcpy(h->MaxNum,p->MaxNum);
t->link->link=h;
h=t->link;
continue;
}
直接插入排序形式上比冒泡排序较为复杂,但时间复杂度有很大降低,同时可以方便地进行限制范围的排序,降低空间复杂度。事实上本算法在形式上也有很大的提升空间。
主界面(本部分图均略)
可以使用括号中的大写字母来选择自己所要的功能。
一般浏览用户可以直接点Q来查询航班信息。
这时点击任意键确认
可以按要求查询航班。按B可以返回上一界面
想要订票首先要成为注册用户登录。如果不是注册用户要先注册
在主菜单中点R注册进入注册界面。
然后按要求输入你想要的用户名与密码。如果提示用户名重复请重新输入一个新的用户名与密码如下图
成功后进入用户登录界面进行订票等操作
购票员与管理员可以进入管理员登录界面进入各自登录界面
购票员界面
管理员界面
进行各自的操作
源程序清单附电子版后