课程设计报告 题目: 保定公交线路查询系统 学 院 数学与计算机学院 学科门类 计算机类 专 业 数电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