课程设计报告
题目: 保定公交线路查询系统
学 院 数学与计算机学院
学科门类 计算机类
专 业 数电2班
学 号 2100435xxx
姓 名 魏xx
指导教师 石xx
2012年 6 月 30 日
1、需求分析
信息记录要存放到文件中去,因而要实现文件的输入输出操作;要实现数据的追加、删除、修改、显示以及公交路线的查询功能,因而要实现插入、删除、修改和显示操作;要实现按照起始站和发车站、路线编号、的查询的功能;另外还应该提供键盘式选择菜单以实现功能选择。
2、总体设计
(1)数据插入模块
输入数据,然后采用追加方式写文件。
(2)数据修改模块
首先将文件信息接入链表,用户输入路线编号,查出该路线,然后由用户决定是修改线路编号还是站点名称。
(3)数据删除模块
删除一条记录,用链表很方便。用户输入要删除的路线编号,链表遍历查找,找到后直接删除。
(4)数据显示模块
链表遍历输出,采用分屏显示,每屏10条记录。
(5)数据查询模块
链表遍历,按公交线路编号查询,按起始站、发车站查询。
3 详细设计
主要包括各模块功能说明,程序流程图,实现该功能的函数名称、入口及出口参数说明,函数调用关系描述,算法实现等。
(1)结构体:struct name
{
//int num; 每天路线站点的编号,因为本程序按站点顺序读入,故略去此项
char nam[20];
};
struct bus
{
int num;
name stop[size2];
};
bus rout;
struct node
{
int num;
name stop[size2];
node *next;
};
node *head=NULL,*temp=NULL,*tail=NULL;
第一个是每天线路的站定名称,第二个是追加时线路信息,第三个是文件读入链表的结构体指针
(2)数据插入模块
追加方式写文件,ofstream fout("bus_station.txt",ios::app);包含于<fstream.h>
cin>>rout.num;
fout<<" "<<rout.num<<" ";采用键盘输入,间接存磁盘的方式
(3)数据修改模块
首先将文件信息接入链表,用strcmp遍历查找用户要修改的线路,由用户输入:cin>>num; if(num==1){修改线路} ;if(num==2){修改站点};如果修改线路名称,直接cin>>cur->num;如果修改线路某站点名称,遍历找到该线路,由用户键入站点名称,然后直接cin>>cur->stop[k].nam;
(4)数据删除模块
删除一条记录,用链表很方便。具体做法我参考的是C++课本单向链表这一节。
(5)数据显示模块
链表遍历输出,采用分屏显示,用的是清屏函数system(“cls”),包含于<stdlib.h>。getch();是为了定屏,实现任意键继续的功能。每屏10条记录,用一个counter计数器即可。
(6)数据查询模块
具体查找方法参考的是C++课本链表章节,链表遍历。
4 调试与测试
调试中出现的问题主要涉及文件的读取与存储,因为与链表结合起来使用,难免有些问题,认真调试,还是能运行的。
5 总结
由于这次课设要求跟平时老师让做过的<商品管理系统>差不多,因为之前对链表、结构体比较熟悉,所以想把文件和链表结合起来,查找删除修改比较方便。最后把修改过的链表重新读入文件,实现对文件的同样操作。
这次的收获较大的是对C++面向结构的知识有个较全面的认识,自学文件这节时,我是C ,C++一块看的,结合网上的对<fstream.h>中的一些函数的详解,另外还学到关于优化算法和C++类的一些知识,因为想在假期学习数据结构,所以这次用到的只是以前熟练的C++语法,在算法上效率应该很低。所以想在以后懂得的知识更多后,再进一步优化算法。这个程序用2天的时间写完,1天时间调试和写报告,大概的思路是清晰的。但我对直接读取文件,直接查找修改文件中间某一部分还不是很懂, fread(buffer,size,count,fp) ,fwrinte(buffer,size,count,fp)与结构体一起使用时还是会出问题。但fscanf ,fseek ofstream fout("bus_station.txt",ios::app);结合链表能解决问题。
参考文献:
C++课本;
附录:
#include<iostream.h>
#include<fstream.h>
#include<stdio.h>
#include<string.h>
#include<conio.h>
#define size1 30 //路线条数上限 ,size1必须为文件中实际线路条数!!!
#define size2 50 //每条路线的站点数 的上限,一般的站点数再20~30左右吧,本实验假设为10~20,简单化嘛
struct name
{
//int num; 每天路线站点的编号,因为本程序按站点顺序读入,故略去此项
char nam[20];
};
struct bus
{
int num;
name stop[size2];
};
bus rout;
struct node
{
int num;
name stop[size2];
node *next;
};
node *head=NULL,*temp=NULL,*tail=NULL;
/********************************插入线路*****文件的存入***************************************************/
void cunru()
{
int a,j=0;
ofstream fout("bus_station.txt",ios::app);
if(!fout)
cerr<<"打开错误!";
else
{
cout<<"请输入路线编号:"<<endl;
cin>>rout.num;
fout<<" "<<rout.num<<" ";
for(j=0;j<size2;j++)
{
cout<<"按1继续存 站点,2退出:";
cin>>a;
if(a==2)
break;
cout<<"请输入站点"<<j+1<<"的名称:"<<endl;
cin>>rout.stop[j].nam;
fout<<rout.stop[j].nam<<" ";
}
cout<<endl;
fout<<"end"; //fout<<"end ";
}
}
/***************************************读取信息到链表*******************************************/
node *duqu()
{
int k;
char a[20],b;
FILE *fp;
if((fp=fopen("bus_station.txt","r"))==NULL)
{
cout<<"无法打开文件!"<<endl;
return 0;
}
head=new node; //分配内存
if(head==NULL)
{
cout<<"内存分配不成功\n";
return 0;
}
else
{
fscanf(fp,"%d ",&(head->num));
for(k=0;k<size2-1;k++)
{
fscanf(fp,"%s",a);
if(strcmp(a,"end")==0)
{
strcpy(head->stop[k].nam,"end");
break;
}
else
{
fseek(fp,-strlen(a),SEEK_CUR); //a用来检测路线是否"end"
fscanf(fp,"%s ",head->stop[k].nam); //把站点从文件中链入链表
}
}
head->next=NULL;
tail=head;
while(!feof(fp)) // feof(fp)检测文件是否到末尾
{
temp=new node;
fscanf(fp,"%d ",&(temp->num)); //这里%d后面的空格不要舍去,方便知道fscanf是如何从文件读取信息的
for(k=0;k<size2-1;k++) //k相当计数器,把文件"end"字符串之前的站点名称连入链表
{
fscanf(fp,"%s",a);
if(strcmp(a,"end")==0)
{
strcpy(temp->stop[k].nam,"end");
break;
}
else
{
fseek(fp,-strlen(a),SEEK_CUR); //a用来检测某条路线是否遇到"end"
fscanf(fp,"%s ",temp->stop[k].nam); //把站点从文件中链入链表,%s后面的空格也最好带着。
}
}
temp->next=NULL;
tail->next=temp;
tail=temp;
}
}
return head;
}
/**********************************修改信息***修改线路编号***或者****站点名称*****************************/
node *xiugai()
{
int num;
cout<<"请输入修改线路编号:";
cin>>num;
node *cur=head;
while(cur)
{
if(cur->num==num)
{
cout<<"修改线路编号请按1,修改站点名称请按2:";
cin>>num;
if(num==1)
{
cout<<"线路编号改为:"; //新的线路编号不得与原来所有的编号重复 否则影响查找
cin>>cur->num;
cout<<"恭喜您,编号更改成功!";
return head;
}
if(num==2)
{
char name[20];
int k=0;
int num;
cout<<"原站点名称为:";
cin>>name;
while(strcmp(cur->stop[k].nam,"end")!=0)
{
if(strcmp(cur->stop[k].nam,name)==0)
{
cout<<"站点名称改为:";
cin>>cur->stop[k].nam;
cout<<"恭喜您,站点名称更改成功!";
return head;
}
k++;
}
if((cur->stop[k].nam,"end")==0)
cout<<"抱歉,您输入的原站点名称有误,请检查后再输入:";
}
}
cur=cur->next;
}
if(cur==NULL)
cout<<"抱歉,您输入的线路编号有误,请检查后再输入:";
return head;
}
/***************************************删除一条记录*****删除一条线路***和该线路的所有站点信息**********************/
node *shanchu()
{
int num;
node *pre=NULL;
node *cur=head;
cout<<"请输入删除路线的编号:";
cin>>num;
while((cur!=NULL)&&(cur->num!=num))
{
pre=cur;
cur=cur->next;
}
if(cur==NULL) //遍历未找到编号num的线路
{
cout<<"抱歉,不存在此路线,请检查后输入!";
return head;
}
if(pre==NULL) // 删除首条线路
{
head=head->next;
cout<<"恭喜您,该线路已经成功删除!";
}
else
{
pre->next=cur->next;
cout<<"恭喜您,该线路已经成功删除!";
}
delete cur;
return head;
}
/*********************************显示线路信息****分屏显示*****每屏显示10条线路信息*************************/
void xianshi()
{
node *cur=head;
int counter=0,i;
int num;
for(;cur!=NULL;)
{
i=0;
cout<<cur->num<<" ";
while(strcmp(cur->stop[i].nam,"end")!=0)
{
cout<<cur->stop[i].nam<<" ";
i++;
}
//cout<<"end";
cout<<endl;
cur=cur->next;
counter++; //计数器
if(counter%10==0)
{
cout<<"\n按任意键翻页:";
getch();
system("cls");
}
continue;
}
return ;
}
/*******************************查询*****线路****发车站*******起始站****************/
node *chaxun()
{
node *cur=head;
int num,i;
char name[20];
cout<<"按公交线路编号查询请按1,按发车站查询请按2,按起始站查询请按3:";
cin>>num;
if((num!=1)&&(num!=2)&&(num!=3))
{
cout<<"抱歉,请按要求键入!";
return head;
}
if(num==1)
{
cout<<"请输入线路编号:";
cin>>num;
cout<<endl<<endl;
cout<<"以下是"<<num<<"号路线站点信息:"<<endl;
while(cur)
{
if(cur->num==num)
{
i=0;
cout<<cur->num<<" ";
while(strcmp(cur->stop[i].nam,"end")!=0)
{
cout<<cur->stop[i].nam<<" ";
i++;
}
return head;
}
cur=cur->next;
}
if(cur==NULL)
cout<<"抱歉,不存在您要查询的线路!"<<endl;
return head;
}
//查询以XX为发车站点的线路编号,可以同时有多条线路从XX出发。
if(num==2)
{
cout<<"请输入发车站点名称:";
cin>>name;
cur=head;
cout<<endl<<endl<<"以下是以 "<<name<<" 为发车站点的线路编号:"<<endl;
while(cur)
{
if(strcmp(cur->stop[0].nam,name)==0)
{
cout<<cur->num<<"路 ";
}
cur=cur->next;
}
return head;
}
//查询经过某某站点的路线编号 ,即按起始站查询线路
if(num==3)
{
cout<<"请输入起始站名称:";
cin>>name;
cur=head;
cout<<"以下是经过 "<<name<<" 的线路:"<<endl;
while(cur)
{
i=0;
while(strcmp(cur->stop[i].nam,"end")!=0)
{
if(strcmp(cur->stop[i].nam,name)==0)
cout<<cur->num<<"路 ";
i++;
}
cur=cur->next;
}
return head;
}
return head;
}
/**********************************将链表中修改过的信息重新存入文件*********************************/
void cunru__wenjian()
{
ofstream fout("bus_station.txt",ios::out);
node *cur=head;
int k;
while(cur->next!=NULL)
{
k=0;
fout<<cur->num<<" ";
while(strcmp(cur->stop[k].nam,"end")!=0)
{
fout<<cur->stop[k].nam<<" ";
k++;
}
fout<<cur->stop[k].nam<<" "; //把end存入线路最后,当做线路结束的标志
cur=cur->next;
}
k=0;
fout<<cur->num<<" ";
while(strcmp(cur->stop[k].nam,"end")!=0)
{
fout<<cur->stop[k].nam<<" ";
k++;
}
fout<<"end"; //把end存入线路最后,当做线路结束的标志
}
/******************************************前言*******************************************************/
void qianyan()
{
cout<<"\n\n* * * * * * * * *欢 迎 您 使 用 保 定 公 交 路 线 查 询 系 统* * * * * * * * *\n\n";
cout<<"\n\t本程序能实现对公交路线插入、修改、删除、显示、公交线路的查询、\n\t站点查询问题!\n\n";
cout<<"\n\t为方便您的使用,本程序目前已经设置好文件的内容,如果您想修改\n\t文件内容请按照菜单提示进行。\n\n";
cout<<"\t您可以直接按提示语进行简单操作; 程序目前只是处于测试阶段,尚未\n\t完善。无法实现更为复杂的功能\n\n";
cout<<"\t如果出现程序不能解决的问题,请用户谅解! O(∩_∩)O谢谢! \n\n\n\n";
cout<<"\t\t制作人:河北大学数计学院2011级数电2班 魏珊珊\n\n";
cout<<"\n\n\n\n"; //按任意键继续!
}
/**********************************************主函数**************************************************/
int main()
{
int input;
qianyan(); //前言
cout<<"按任意键继续:";
getch();
system("cls"); //清屏
cout<<"\t☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆\n";
cout<<"\t 欢 迎 使 用 公 交 查 询 系 统 \n\n";
cout<<"\t 1 公 交 线 路 插 入 \n\n";
cout<<"\t 2 公 交 线 路 修 改 \n\n";
cout<<"\t 3 公 交 线 路 删 除 \n\n";
cout<<"\t 4 公 交 线 路 显 示 \n\n";
cout<<"\t 5 公 交 线 路 查 询 \n\n";
cout<<"\t 6 退 出 查 询 系 统 \n\n";
cout<<"\t☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆\n";
cout<<"请选择操作:";
cin>>input;
while(input)
{
duqu(); //文件读取到链表。
switch(input)
{
case 1:
cunru(); //追加方式插入线路
break;
case 2:
xiugai(); //修改
cunru__wenjian(); //链表存入文件
break;
case 3:
shanchu(); //删除
cunru__wenjian(); //链表存入文件
break;
case 4:
system("cls");
xianshi(); //显示
break;
case 5:
chaxun(); //查询
break;
case 6:
system("cls");
cout<<"\n\n\n\n\n\n\n\n\n\t\t 感谢您的使用,O(∩_∩)O谢谢!\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n";
getch();
return 0;
}
delete head;
cout<<"\n请选择操作:";
cin>>input;
}
return 0;
}
有想要文件的,加我QQ 2639592937