第一篇:泊车管理系统程序设计报告剖析
程序设计报告
(201 / 201 学年 第 二 学期)
专 学 生 班 级 指 导 指 导 日 题 目:泊车管理系统
业
姓 名 学 号 教 师 单 位 计算机软件教学中心 期 201年6月19日
泊车管理系统一、课题内容
模拟一个泊车管理系统,提供车位的管理、泊车、取车等功能,并能查询车位信息,并会运用某种排序算法进行排序操作。通过本课题全面掌握文件、数组的各种操作,以及一些算法思想的应用,实现一个简单的泊车管理系统。
二、需求分析
模块一(密码输入):登陆界面,管理员输入密码,若密码正确,进入操作系统。模块二(信息系统):显示当前时间与车库的基本停车情况以及收费标准。
模块三(停车系统):进入此系统后,输入当前时间和车牌号码,若有空位则停车成功,否则显示车库已满,自动返回上一层操作系统。
模块四(取车系统):进入此系统后,依次输入车牌号码,停车时间,当前时间,若
查找到所输入的车牌号码信息,则显示本次停车应付金额,并显示取车成功。若无输入的车牌号码信息,则显示取车错误并返回上层操作系统。
模块五(退出操作):当程序使用结束的时候,用此模块关闭程序。
三、活动收益
这次的设计课我受益颇多,完全是一次真正的自己动手的程序设计!自己发现问题、解决问题。其中不仅对C和C++的操作有了进一步的掌握还学会了使用VISIO软件并熟悉了DEBUG的使用方法,还了解到了程序设计的书写风格及其注释的格式。
当然,我们这次也遇到了不少问题,好在在老师的悉心教导下,我们攻克了一个又一个难关。
四、遇到的问题及解决方法:
●我们遇到的第一个难关就是把密码以明码的形式输出,好在老师及时提醒,所以我们通过上网查资料,想到可以以真假语句来实现,我们在网上找了了几个类似的程序,熟悉了它们的每一步过程之后,我们就开始自己动手,所以最后我们决定以数组的形式来改写,最后利用FOR循环成功解决了。当然在这次解决中,我们充分发挥了团体合作精神。
●我们当然不是一帆风顺的,遇到的第二个问题是经费设计问题,我们一开始忽略了半个小时这个关键词,直接是不足一个小时按一个小时计算,我们于是动手开始设计相应的程序,我们首先思考是不是可以加上1/2,在一番试验、比较之后,最后我们用 fee=feep(&b[top]->timep)*7语句加上IF的判断语句,我们最后成功设计出来了。●接下来我们在时间差函数的设计上完全摸不着头脑,突然我们想到老师给了我们这个2 函数,我们成功地找到了时间差函数,我们仔细研读了老师给我们的程序,了解它是怎么运行的,之后,我们自己开始开工写出了double feep(time_t* tmp)这样的语句,通过编译、运行,证明了我们程序的正确性,为此我们付出了辛勤的汗水。
●我们也在号码查询这一程序过程卡住了,我们丝毫没有头绪,为此我们天天抢占图书馆,翻阅资料,理解、消化,实在不懂就去机房上网去看详尽的解说,晚上回宿舍继续编写,我们几个人讨论、琢磨,不停地修改、再写,好在不负众望,我们想到了printStar();printLine()语句,最终完成。
我们在这个合作完成中学到的感触最深的就是团队精神的重要性,我们不停地讨论,才使得我们的程序设计不断的完美,虽然可能不是太好,但真的有我们几个的汗水在里面。通过这次实验,我们知道了学知识就是要学以致用,提高动手能力,为此很感谢这次实验。
五、程序代码
#include
{
//parkingLot.top--;
cout<<“top--”;
} printf(“r”);if(hour<10)printf(“0”);printf(“%d:”,hour);if(min<10)printf(“0”);printf(“%d:”,min);if(sec<10)printf(“0”);printf(“%d”,sec);}
void run(){ while(sec!=0||min!=0||hour!=0){ tick();show();} } void set(int h,int m,int s){ hour=h;min=m;sec=s;} };
struct passLot
//小车队列结构 { int num;
//车位号
time_t timep;
//停车时间
char carNum[10];
//停车的车牌号码 };
struct potLot
//停车场栈数据 { int num;time_t timep;char carNum[10];};
void printLine()
//打印下划线(作为主界面图表的框架){ cout<<“ttt___________________________________”< void printStar() //打印星号 { cout< class erroFull //停车位满时异常类 { public: erroFull(){ system(“color Fc”);} void ex(){ cout< //析构函数 };class erroEmp //停车位空时异常类 { public: erroEmp(){ system(“color Fc”);} void ex(){ cout<<“停车场位为空!”< class parkingLot //停车场类 { public: parkingLot(){ passLot* pa; //小车停车指针 potLot* po; //大车停车指针 flag=0; //用来记忆队列(小车)中停车的数量 rear=front=0; //初始化队列头尾 base=0; top=base; //初始化栈头尾 int i=0; //初始化所有 for(;i { pa=(passLot*)malloc(sizeof(passLot));//申请动态空间 a[i]=pa; a[i]->num=i+1; a[i]->carNum[10]='a'; po=(potLot*)malloc(sizeof(potLot)); b[i]=po; b[i]->num=i+1; b[i]->carNum[10]=1; } } ~parkingLot() //清除停车场数据 { cout<<“tt停车场数据已清空。”< void passLG() //小车管理函数 { try { if(flag==20)throw erroFull(); //如果停车位已满,则抛出车位满的异常情况 system(“cls”); //清屏 printStar(); cout<<“tttt您进入了小车停车界面”< cout< cin>>a[rear]->carNum; //得到车牌号 if(strlen(a[rear]->carNum)!=6) { cout<<“tt警告!请将车牌规范化!系统将于一秒后返回!”< _sleep(1000); return;} a[rear]->timep=time(NULL); cout< rear=(rear+1)%PASS; flag++; _sleep(1000); //休眠 } catch(erroFull &err) { err.ex(); } } void potLG() //大车停车函数 { try { if(top==20)throw erroFull(); //车满抛出异常 system(“cls”); //清屏函数 printStar(); //打印星号 cout<<“tttt欢迎进入本泊车管理系统”< cout< cin>>b[top]->carNum; if(strlen(b[top]->carNum)!=6) { cout<<“tt警告!请将车牌规范化!系统将于一秒后将返回!”< _sleep(1000); return;} b[top]->timep=time(NULL); cout< top++; _sleep(1000); //当前休眠一秒 } catch(erroFull &err) { err.ex(); } } void reservation() //预约函数 { int choice=-1;if(top==20&&flag==20)throw erroFull(); // 小车数目满则抛出异常 for(;;){ system(“cls”); //清屏函数调用 printStar(); //打印星号函数 cout<<“tttt欢迎进入本预约管理界面”< printLine(); //划线函数 cout<<“ttt|1.请输入预约的车牌号码ttt |”< printLine(); cout<<“ttt|2.请输入确定预约的车牌号码ttt |”< printLine(); cout<<“ttt|3.返回ttt |”< printLine(); printStar(); //打印星号 cout<<“tt请输入您的选项< 1-3 >:”; //二级菜单函数 cin>>choice; //选择菜单函数 switch(choice){ case 1:cacutime();break; case 2:resure();break; case 3:break; default:system(“color Fc”);cout< _sleep(1000);break;} if(choice==3)break;} return;} void depart() //汽车离开 { int choice=-1;if(top==0&&flag==0)throw erroEmp();for(;;){ system(“cls”);system(“color F0”);printStar();cout<<“tttt欢迎下次光临停车场”< //打印两个空格 printLine();cout<<“ttt|2.小车离开ttt |”< cout<<“tt请输入您的选项< 1-3 >:”;cin>>choice;switch(choice){ case 1:potOut();break; case 2:passOut();break; case 3:break; default:system(“color Fc”);cout< _sleep(1000);break;} if(choice==3)break;} return;} void arrive() //汽车到达 { int choice=-1;if(top==20&&flag==20)throw erroFull(); //小车数目满则抛出异常 for(;;){ system(“cls”); //清屏函数调用 printStar(); //打印星号函数 cout<<“tttt欢迎进入本泊车管理界面”< printLine(); //划线函数 cout<<“ttt|1.大车停车ttt |”< /*打印两个空格*/ printLine(); //划线函数 cout<<“ttt|2.小车停车ttt |”< printLine(); //划线函数 cout<<“ttt|3.返回 ttt |”< printLine(); //划线函数 printStar(); //打印星号 cout<<“tt请输入您的选项< 1-3 >:”; //二级菜单函数 cin>>choice; //选择菜单函数 switch(choice) //选择菜单函数 { case 1:potLG();break; case 2:passLG();break; case 3:break; default:system(“color Fc”); cout< _sleep(1000);break; } if(choice==3)break;} return;} /*void readwriteDAT(){ long *temp;FILE *rf,*wf; rf=fopen(“in.dat” ,“ r”);wf=fopen(“ out.dat” ,“ w”);fscanf(rf,“ %ld” ,&temp);feep(temp);fprintf(wf,“ %ld” ,temp);fprintf(wf,“n”);fclose(rf);fclose(wf);} */ double feep(time_t* tmp) //时间差的计算 { int m=0,min=0,sec=0; //设置数据用来计算时间间隔,停车时、分、秒。 double gap=0,hour=0; local=localtime(tmp); //将存储的时间转化为当地时间日历 cout< //保存停车时刻 min=local->tm_min; sec=local->tm_sec; now=time(NULL);nowp=localtime(&now); cout<<“t当前时间:t”< hour = nowp->tm_hour-hour; //求出停车的时间间隔 min= nowp->tm_min-min;sec= nowp->tm_sec-sec; if(sec<0){min--;sec=60+sec;} //进行秒、分钟、秒时间转换 if(min<0){hour--;min=60+min;} cout<<“t汽车共停t”<< hour<<“小时”<< min<<“分”<< sec<<“秒”< if(min<30) gap=hour+0.5; else gap=hour+1; //停车应收费的时间(单位:小时) return gap;} void cul() { int s=5,m=0,h=0; Clock c; c.set(h,m,s); c.run(); printf(“ntThe time is over!!an”);} void cacutime() //预约时间计算函数 { try { if(top==20)throw erroFull(); //车满抛出异常 system(“cls”); //清屏函数 printStar(); //打印星号 cout<<“tttt欢迎进入预约界面”< cout< cout<<“ttt请输入车牌的数字部分:”; cin>>numCar; cout< top++; _sleep(1000); //当前休眠一秒 cul(); } catch(erroFull &err) { err.ex(); } return;} void resure(){ return;} void passOut() //小车离开 { FILE *out;out = fopen(“out.dat”, “ab+”);try { if(flag==0)throw erroEmp(); double fee=0; system(“cls”); printStar(); cout<<“tttt您进入了小车离开界面”< cout<<“ttt将要离开车的信息清单:”< fprintf(out, “%s”,a[front]->carNum);fee=feep(&a[front]->timep)*5; cout<<“t应缴车费:t”< fprintf(out, “%-6g”,fee); cout<<“___________________________________________________________________________”;//打印线条 cout< cout<<“t本停车场共有20个车位,现共停”< a[front]->carNum[10]=0; front=(front+1)%PASS; flag--; cout< system(“pause”); } catch(erroEmp &err) { err.ex(); } fprintf(out,“n”); fclose(out);} void potOut() //大车离开 { FILE *out;out = fopen(“out.dat”, “ab+”);try { if(top==0)throw erroEmp(); double fee=0; top--; system(“cls”); printStar(); cout<<“tttt您进入了停车场离开界面”< fprintf(out, “%s”,b[top]->carNum); fee=feep(&b[top]->timep)*7; //计费公式,每小时7元 cout<<“t应缴车费:t”< fprintf(out, “%-6g”,fee); cout<<“___________________________________________________________________________”; cout< cout<<“t本停车场共有20个车位,现共停”< b[top]->carNum[10]=0; cout< system(“pause”); } catch(erroEmp &err) { err.ex(); } fprintf(out,“n”); fclose(out);} void searchNum() //查询车牌号码 { char numCar[20];int i=0;flag=1;cout<<“ttt请输入车牌的数字部分:”;cin>>numCar;if(strlen(numCar)==6){ for(;i if(strcmp(a[i]->carNum,numCar)==0) { cout< flag=0; } } if(flag)for(i=0;i if(strcmp(b[i]->carNum,numCar)==0){ cout< flag=0; } } if(flag)cout< cout<<“请规范化车牌!”< void searchPot() //按车wei查找函数 { int potCar, nn;cout<<“tt操作说明:按照停车类型加位置来输入所要查找的车位信息ntt如:大车10号位,即输入110。大车三号位,103。小车5号位,205”< if(potCar/100==1) { nn=potCar%100-1; if(b[nn]->carNum[10]==0)cout<<“tt您所查询的车位没有停车”< else cout<<“停车场”< } if(potCar/100==2){ nn=potCar%100-1; if(a[nn]->carNum[10]==0)cout<<“tt您所查询的车位没有停车”< else cout<<“便车道”< void search() //号码查询 { int choice=-1;if(top==0&&flag==0)throw erroEmp();for(;;){ system(“cls”); system(“color F0”); printStar(); cout<<“tttt您进入了号码查询界面”< printLine(); cout<<“ttt|1.根据车牌号码查询tt |”< //打印两个空格 printLine(); cout<<“ttt|2.直接查询指定车位tt |”< printLine(); cout<<“ttt|3.返回ttt|”< printLine(); printStar(); cout<<“tt请输入您的选项< 1-3 >:”;cin>>choice;switch(choice){ case 1:searchNum();break;case 2:searchPot();break;case 3:break;default:system(“color Fc”);cout< _sleep(1000);break;} if(choice==3)break;} return;} private: int flag,front,rear,top,base; 访问栈和队列 passLot* a[PASS]; 式存储栈和队列,并且都设为20个车位 potLot* b[POT];tm* local,*nowp;time_t now; 置时间型变量 }; 结束 void password() */ { 16 //设置 //以顺序方 //设 //停车场类 /*密码 system(“color 0A”);int a;int i=0;char s1[6]={“admin”};char s2[6];char ch;do { if(i<3){ printf(“n 请输入管理员密码,您有 %d 次机会:”,3-i); int j=0,n=strlen(s1);while(n--){ ch=getch();//读取字符,不显示 if(ch!='n')//这边可以加上一些限制,如字符类型,退格等 { putchar('*');s2[j++]=ch;} } s2[strlen(s1)]=' ';if(!strcmp(s1,s2)) a=1;else { a=0;} if(a==1)的密码str1 和设定的密码str2,输出“密码正确”。*/ {printf(“nnt授权成功!准许进入!n nttt后.................nn”); _sleep(1000);} else if(a==0){ system(“color 0c”);printf(“ntI'm sorry,The code is wrong!”);if(i<2)printf(“Please try again!n”);} i++;} else { printf(“nn 对不起,您登陆失败!t请按任意键退出!n”);exit(0);} /*比较输入进入中,请稍17 } while(a==0);system(“cls”);} void main()//程序运行主函数 { system(“color F6”);printf(“n”);printf(“t ----------------------n”); //初始欢迎界面 printf(“t ----------------------n”);printf(“n”);printf(“t n”);printf(“t n”);printf(“t 欢迎进入本泊车场管理系统 n”);printf(“t n”);printf(“t n”); printf(“t ----------------------n”);printf(“t ----------------------n”);printf(“tttttt 出品人:XXX n”);printf(“n”);printf(“n”);printf(“n”); system(“PAUSE”); //清屏操作 system(“CLS”); password(); //密码函数 parkingLot a;int choice=-1;for(;;) //使主界面能够自动初始化和重复使用 { system(“cls”); //清屏18 函数 system(“color F0”); //设为背景为白色前景色为黑色 printStar();cout<<“tttt欢迎进入停车场管理系统”< //时间结构或者对象 t=time(NULL); //获取当前系统的日历时间 cout<<“ttttt”<<“当前时间:”< //显示当前时间 printLine();cout<<“ttt|1.汽车到达ttt |”< /*打印两个空格*/ printLine();cout<<“ttt|2.汽车离去ttt |”< try{ a.arrive(); } catch(erroFull &erro) { erro.ex(); } break;case 2:a.depart();break;case 3:a.search();break;case 4:a.reservation();break;case 5:break;default:system(“color Fc”);cout< _sleep(2000);;break;} if(choice==5)break;} return;} 20 XXXXXXXXXXXC/C++程序设计实训 电话簿管理系统 学生姓名 ×××× 学 号 ×××× 所在学院 ×××× 专业名称 ×××× 班 级 ×××× 指导教师 XXX XXXXXXXXXXXXXXXX XXXXXXXXXXXX 目 录 1.前言··················································································································· 3 2.设计目的··········································································································· 3 3.功能描述··········································································································· 3 4.总体设计··········································································································· 4 1、功能模块设计···························································································· 4 2、数据结构设计···························································································· 6 3、函数功能描述···························································································· 7 5.程序实现··········································································································· 7 1、源程序(略)···························································································· 7 2、运行结果···································································································· 7 6.小结··················································································································· 9 1.前言 随着科技的进步和信息产业的飞速发展,电话簿成为了现代生活中一个重要的工具。本电话簿管理系统利用计算机对通讯录进行统一管理,包括添加、修改、查询记录等功能,实现通讯录管理工作的系统化、规范化和自动化,为人们的工作和生活提供便利。本程序是利用结构数组实现此电话簿管理系统。 2.设计目的 本程序旨在训练基本编程能力,了解管理信息系统的开发流程,熟悉C语言的文件和结构数组的各种基本操作。本程序中涉及结构体、数组、文件等方面的知识。通过本程序的训练,能对C语言的文件操作有一个更深刻的了解,掌握利用数组存储结构实现电话簿管理的原理,为进一步开发出高质量的信息管理系统打下坚实的基础。 3.功能描述 如图1所示,电话簿管理系统主要利用数组来实现,其数组元素是结构体类型,整个系统由如下几大功能模块组成。 电话簿管理系统输入记录模块查询记录模块更新记录模块输出记录模块从文件读入从键盘读入按姓名查询按电话查询修改记录删除记录插入记录排序记录输出至文件输出至屏幕(1)输入记录模块。输入记录模块主要完成将数据存入数组中的工作。在此电话簿管理系统中,记录可以从以文本形式存储的数据文件中读入,也可从键盘逐个输入记录。记录由与联系人有关的基本信息字段构成。当从数据文件中读入记录时,它就是在以记录为单位存储的数据文件中,将记录逐条复制到结构体类型的数组元素中。 (2)查询记录模块。查询记录模块主要完成在数组中查找满足相关条件的记录。在此电话簿管理系统中,用户可以按照联系人姓名或联系人电话号码在数组中进行查找。若找到该记录,则以表格形式打印出此记录的信息;否则,返回一个-1的值,并打印出未找到该记录的提示信息。 (3)更新记录模块。更新记录模块主要完成对记录的维护。在此电话簿管理系统中,它实现对记录的修改、删除、插入和排序操作。一般而言,系统进行了这些操作之后,需要将修改的数据存入源数据文件。 (4)输出记录模块。输出记录模块主要完成两个任务。第一,它实现对记录的存盘操作,即将数组中各元素中存储的记录信息写入数据文件中。第二,它实现将数组中存储的记 图1 电话簿管理系统功能模块 录信息以表格的形式在屏幕上打印显示出来。 4.总体设计 1、功能模块设计 (1)主控main()函数执行流程 电话簿管理系统执行主流程如图2所示。它先以可读写的方式打开文本类型的数据文件,此文件默认为“c:telephon”,若该文件不存在,则新建此数据文件。当打开文件操作成功后,从文件中一次读出一条记录,添加到新建的数组中,然后执行显示主菜单和进入主循环操作,进行按键判断。值得一提的是,文本类型文件与二进制类型文件不同,它可以使用Windows自带的记事本打开并查看到存储的文件内容。 开始以可读写的方式打开一个数据文件将此文件的内容读出,并存入一个新的结构体类型的数组中调用emnu()菜单函数进入while(1)主循环输入0~8中的一个数值,选择相应操作输入是否为0?是否判断键值,调用相应函数,完成相应功能是否已对修改进行了存盘?否调用Save()函数,进行写数据文件操作是结束 图2 主控函数执行流程图 在判断键值时,有效的输入为0-8之间的任意数值,其他输入都被视为错误按键。若输入为0(即变量select=0),则会继续判断是否在对记录进行了更新操作之后进行了存盘操作,若未存盘,则全局变量saveflag=1,系统会提示用户是否需要进行数据存盘操作,用户输入 Y或y,系统会进行存盘操作。最后,系统执行退出电话簿管理系统的操作。 若选择1,则调用Add()函数,执行增加记录操作;若选择2,则调用Disp()函数,执行将记录以表格形式打印输出至屏幕的操作;若选择3,则调用Del()函数,执行删除记录操作;若选择4,则调用Qur()函数,执行查询记录操作:若选择5,则调用Modify()函数,执行修改记录操作;若选择6,则调用lnsert()函数,执行插入记录操作;若选择7,则调用SelectSort()函数,执行按升序排序记录的操作;若选择8,则调用Save()函数,执行将记录存入磁盘中的数据文件的操作:若输入为0-8之外的值,则调用Wrong()函数,给出按键错误的提示。 (2)输入记录模块 输入记录模块主要实现将数据存入数组中。当从数据文件中读出记录时,它调用fread(&tele[count],sizeof(TELEBOOK), l,fp)文件读取函数,执行一次从文件中读取一条电话簿记录信息存入某个数组元素中的操作,并且这个操作在main()中调用执行,即在电话簿管理系统进入显示菜单界面时,该操作己经执行了。若该文件中没有数据,则系统会提示数组为空,没有任何记录可操作,此时,用户应选择1,调用Add()函数,进行记录的输入,即完成在数组中添加元素的操作。 (3)查询记录模块 查询记录模块主要实现在数组中按联系人姓名或电话查找满足条件的记录。在查询函数Qur()中,为了遵循模块化编程的原则,对在数组中进行的记录定位操作设计成了一个单独的函数int Locate(TELEBOOK temp[],int n,char findmess[],char nameorphonenum[]),参数findmess[]保存要查找的具体内容,nameorphonenum[]保存要查找的字段(值为字特串类型的name或phonenum),若找到该记录,则返回指向该记录的数组元素的下标;否则,返回一个-1的值。 (4)更新记录模块 更新记录模块主要实现了对记录的修改、删除、插入和排序操作。因为记录是以数组的结构形式存储的,所以这些操作都在数组中完成。下面分别介绍这4个功能模块。 1)修改记录 修改记录操作需要对数组中目标元素的数据域中的值进行修改,它分两步完成。第一步,输入要修改的联系人姓名,输入后调用定位函数Locate()在数组中逐个对联系人姓名字段的值进行比较,直到找到该联系人姓名的记录;第二步,若找到该记录,修改除记录编号之外的各字段的值,并将存盘标记变saveflag置1,表示已经对记录进行了修改,但还未执行存盘操作。 2)删除记录 删除记录操作完成删除指定联系人姓名或电话号码的记录,它也分两步完成。第一步,输入要修改的联系人姓名或电话号码,输入后调用定位函数Locate()在数组中逐个对联系人姓名或电话号码字段的值进行比较,直到找到该联系人姓名或电话号码的记录,返回指向该记录的数组元素下标;第二步,若找到该记录,则从该记录所在元素的后续元素起,依次向前移一个元素位置,有值的数组元素个数减1,其具体过程如图3所示,在删除了数组元素A2后,数组元素A3和A4向前移动了一个位置 A0删除A2前A0删除A2后A1A1A2A3A3A4A4 图3 数组中删除记录示意图 3)插入记录 插入记录操作完成在指定记录编号的随后位置插入新的记录。首先,它要求用户输入某个记录编号,新的记录将插入在该记录之后、然后,提示用户输入一条新的记录的信息,这些信息保存在新结构体类型的数组元素的各字段中;最后,将该元素插入在已经确认位置的记录编号之后。它的具体插入执行过程如图4所示,新元素B1准备插入至已有5个元素的数组中,插入位置为元素A2之后。这具体过程为:先调用Locate()函数找到A2在数组中的下标,从A4开始,往后移动,至A2停止移动,然后在原A3的位置插入元素B1。 插入B1A0插入B1前A0插入B1后A1A2B1A3A4A1A2A3A4 图4 数组中插入记录示意图 4)排序记录 选择排序法也属于内部排序法中的一种,它是运用字段值比较后,从欲排序的数组元素中,按指定规则选出其字段值最小的元素,并依原则交换数组元素位置后,更新欲排序的数组元素,以达到排序的目的。这里我们采用这种排序法来实现按照记录编号或联系人姓名字段的值从低到高对记录进行升序排序。对按照记录编号排序方式而言,我们将按其数值大小来排序;对按照联系人姓名排序方式而言,我们将按其姓名字符ASCII码的大小来排序。 选择排序的方法为:从欲排序的n个数组元素中,以线性查找的方式找出最小的元素和第一个元素交换,再从剩下的(n-1)个数组元素中,找出最小的元素和第二个元素交换,以此类推,直到所有元素均已排序完成。 将相邻的两个数组元素的电话簿字段的值进行比较,若左边的值小于右边的值,则将此两个元素的值进行交换;若左边的值大于等于右边的值,则此两个值的位置不变。右边的值继续和下一个值做比较,重复此动作,直到比较到最后一个值,最终实现了升序排序。选择排序法是最简单的排序法,但选择排序法所需的排序时间比其他排序法长。 (5)输出记录模块 当把记录输出至文件时,调用fwrite(&temp[i],sizeof(TELEBOOK),L,fp)函数,将数组元素temp[i ]中各字段的值,写入文件指针fp所指的文件:当把记录输出至屏幕时,调用void Disp()函数,将数组中存储的记录信息以表格的形式在屏幕上打印出来。 2、数据结构设计 本程序定义了结构体telebook,用于存放联系人的基本信息。这里仅有3 个与联系人有关的字段,读者可以按照需要扩展相关字段。 typedef struct telebook { char num[4];char name[10];char phonenum[15];char address[20];}TELEBOOK;其各字段的值的含义如下: num[4]:保存记录编号。 name[10]:保存联系人姓名。 phonenum[15]:保存联系人的电话号码。 address[20]:保存联系人地址。 3、函数功能描述 1)printheader()函数原型:void printheader()printheader()函数用于在表格形式显示记录时,打印输出表头信息。2)printdata()函数原型:void printdata(TELEBOOK pp)printdatan()数用于以表格显示的方式,打印输出单个数组元素pp中的记录信息。3)Disp()函数原型:void Disp(TELEBOOK temp[],int n)Disp()函数用于显示temp数组中存储的n条记录,内容为telebook结构中定义的内容。其余函数功能描述省略,请同学们在自己写的时候写完整。 5.程序实现 1、源程序(略) 2、运行结果 (1)主界面 图5 主界面 当用户刚进入电话簿管理系统时,其主界面如图5所示。此时,系统己经将“c:telephon”文件打开,若文件不为空,则将数据从文件中逐条记录读出,并写入数组中。用户可选择0-8之间的数值,调用相应功能进行操作。当输入为0时,退出此管理系统。 (2)输入记录 当用户输入1并按Enter键后,即可进入数据输入界面。其输入记录过程如图6所示,这里输入了3条记录。当用户输入为0的记录编号时,它会结束输入过程,返回到主菜单界面。 (3)显示记录 当用户执行了输入记录或已经从数据文件中读取了记录之后,即可输入2并按Enter键,查看当前数组中的记录情况,如图7所示,此时表中有3条记录。 图6 输入记录 图7 显示记录 (4)删除记录 当用户输入3并按Enter键后,即可进入记录删除界面。其删除记录过程如图8所示,这里按联系人姓名删除了一条姓名为A1的记录。 图8 删除记录 (5)查找记录 当用户输入4并按Enter键后,即可进入记录查找界面。其查找记录过程如图9所示,8 用户可按姓名或电话号码进行记录查找。 图9 查找记录 (6)修改记录 当用户输入5并按Enter键后,即可进入记录修改界面。其修改记录过程如图10所示,这里修改了姓名为a2的联系电话和地址字段。 图11 修改记录 (7)插入记录 当用户输入6并按Enter键后,即可进入记录插入界面。其插入过程如图11所示,这里在记录编号为3的记录后插入了一条记录编号为5的记录。 (8)排序记录 当用户输入7并按Enter键后,即可进入记录排序界面。用户可以选择按照记录编号或联系人姓名进行排序,图12为按记录编号进行记录升序排序的结果。 (9)保存记录 当用户输入8并按Enter键后,即可进入记录保存界面。其保存结果提示信息如图13所示,这里有3条记录已经存储至磁盘数据文件c:telephon中。 6.小结 本文介绍了电话簿管理系统的设计思路及其编程实现,重点介绍了功能模块的设计原理和利用数组存储结构实现电话簿管理的过程。通过本程序的开发使我熟悉C语言下的文件和数组操作,了解管理信息系统(MIS)的开发原理,并注意利用选择排序法来实现数组元素 排序的特点。 利用本电话簿管理系统可以对通讯录进行日常维护和管理。 C语言程序设计 实验报告 题 目: 图书管理管理系统 院 系: 信息科技学院 专 业: 姓 名: 学 号: 指导教师: 杨呈勇 日 期: 09-09-18 问题定义 …………………………………………………………………………..3 2 系统设计 ……………………………………………………………………3 2.1 总体设计………………………………………………………………………………4 2.2 详细设计………………………………………………………………………………4 2.2.1 借书模块 ……… ………………………………………………… 4 2.2.2 图书维护………………………………………………………………………… 5 ① 新增记录 …………………………………………………………………… 5 ② 更改系统…………………………………………….………………… 6 ③删除系统 …………………………………………… 6 ④ 查找系统……………………………………………….………………….6 ⑤ 显示系统 ………………………………………………………………….7 3 系统实现 ………………………………………………………………………10 3.1 编码 ………………………………………………………………………8 3.1.1 程序预处理 ……….……………………………………………………………9 3.1.2 主函数main()……….……………………………………………………….9 4 系统维护 ………………………………………………………………………16 5 归纳总结 ………………………………………………………………………16 5.1 开发经验 ………………………………………………………………………16 5.2 实训中遇到的问题及解决方法 ………………………………………………16 5.3 设计中的不足之处……………………………………………………………………16 5.4 感想和心得体会 ……………………………………………………………………16 图书管理系统 本题目设计目的是训练学生的基本编程能力,了解管理信息系统的开发流程,熟悉C语言的文件和单链表的各种基本操作。本程序中涉及结构体、单链表、文件及各种语句的运用如for();switch();if….else等方面的知识。通过本程序的训练,使学生能对C语言的文件操作有一个更深刻的了解,初步掌握链表的一些结构及构成。掌握利用单链表存储结构实现对学生成绩管理的原理,为进一步开发出高质量的管理信息系统打下坚实的基础。 1、问题定义 图书信息包括:编号、书名、作者名、分类号、出版单位、出版时间、库存数量,价格等。试设计一图书信息管理系统,使之能提供以下功能:(1)系统以菜单方式工作 (2)图书信息录入功能(图书信息用文件保存)(3)图书信息浏览功能(4)图书信息查询功能 查询方式:可以按书名,按作者名,按出版单位,按出版时间进行查询。(5)图书信息的删除与修改 在问题定义阶段要考虑题目的可行性和需求分析,接下来进入开发阶段,完成系统设计和系统实现的任务。 2、系统设计 2.1 总体设计 采用模块化的程序设计方法,即将较大的任务按照一定的原则分为一个个较小的任务,然后分别设计各个小任务。需要注意的是划分出来的模块应该相对独立但又相关,且容易理 解。可以用模块化层次结构图(即模块图)来分析其任务的划分,一般从上到下进行,最上面一层是主模块,下面各层是其上一层模块的逐步细化描述。 图2.1 图书管理系统功能模块图 本图书管理系统要求采用单链表实现,如图2.1所示,它由如下四大功能模块组成: 借书模块。通过输入读者的编号和图书的编号,查找到要该借的书,完成借书这一项任务 还书模块。通过输入读者的编号和图书的编号,查找到要该还的书,完成还书这一项任务 图书维护模块。完成对图书信息的维护。在此图书管理系统中,它实现了对图书信息的新曾、更改、删除、查找和显示操作,并将追加后的数据存入源数据文件。读者维护模块。一是实现对读者记录的存盘,即将读者信息写入数据文件中; 2.2 详细设计 2.2.1 借书模块 通过输入读者的信息和要借的书的编号。系统显示相应的内容,若该文件中没有数据,系统会提示单链表为空,没有任何读者记录或图书操作,此时,用户应选择调用create()函数,进行读者记录的输入,即完成在单链表1中添加记录的操作。值得一提的是,这里的字符串和数值的输入分别采用了函数来实现,在函数中完成输入数据任务,并对数据进行条件判断,直到满足条件为止,这样一来,大大减少了代码的重复和冗余,符合模块化程序设计的特点。 2.2.2 还书模块 还书模块主要实现了在单链表中按读者和图书的编号查找满足相关条件的借书记录。在 用户选择4,调用查询函数search()中,为指向保存了读者信息的单链表的首地址的指针变量。为了遵循模块化编程的原则,我们将在单链表中进行的指针定位操作,设计一个 int retbook(int bookid) { for(int i=0;i { if(borbook[i]==bookid) { borbook[i]=0; return 1; } } return 0; } //读出读者信息 void disp() { cout << setw(5)<< no < for(int i=0;i if(borbook[i]!=0) cout << borbook[i] << “|”; cout << “]”< } }; 若没有该记录,则显示无此记录,返回到上一操作。 2.2.3 图书维护模块 此模块主要实现了对图书记录的新增、更改、删除、查找和显示操作。因为图书记录是以单链表的结构形式存储的,所以这些操作都在单链表中完成。下面分别介绍着4个功能模块。 ①新增记录。该操作需要对单链表中目标节点的数据域中的值进行追加新增要输入图书的编号和书名,int addbook(int n,char *na) { Book *p=query(n); if(NULL==p) { top++; book[top].addbook(n,na); return 1; } return 0; } ②更改系统。该操作可以将原本错误的图书记录更改,将之改为正确的记录。首先输入原来的记录的图书的编号,在此之后输入新的记录的书名。 ③删除系统。该操作可以将原本记录得图书信息,在不用之后选择将此删除的一种方法,在弹出的窗口输入原来的图书的编号,就可以将之删除。 ④ 查找系统。该操作可以帮助读者快速找到将要借的图书,只要输入图书的编号,如果有这本书,就将显示出。反之就会显示不存在。Book *query(int bookid) { for(int i=0;i<=top;i++) if(book[i].getno()==bookid &&book[i].gettag()==0) { return &book[i]; } return NULL; } ⑤显示系统。该操作可以显示出图书现在的信息。cout << “输入图书编号:”< cin >> bookid; cout << “输入图书书名:”< cin >> bname; addbook(bookid,bname); break; case '2': cout << “输入图书编号:”< cin >> bookid; b=query(bookid); if(b==NULL) { cout << “ 该图书不存在 ”< break; } cout << “输入新的书名:”< cin >> bname; b->setname(bname); break; case '3': cout <<“ 读入图书编号:”< cin >> bookid; b=query(bookid); if(b==NULL) { cout <<“ 该图书不存在” << endl; break; } b->delbook(); break; case '4': cout << “ 读入图书编号:”< cin >> bookid; b=query(bookid); if(b==NULL) { cout <<“ 该图书不存在”<< endl; break; } b->disp(); break; case '5': disp(); break; case '6': clear(); break; default:cout<<“输入错误,请从新输入:”; } } }cout << “输入图书编号:”< cin >> bookid; cout << “输入图书书名:”< cin >> bname; addbook(bookid,bname); break; case '2': cout << “输入图书编号:”< cin >> bookid; b=query(bookid); if(b==NULL) { cout << “ 该图书不存在 ”< break; } cout << “输入新的书名:”< cin >> bname; b->setname(bname); break; case '3': cout <<“ 读入图书编号:”< cin >> bookid; b=query(bookid); if(b==NULL) { cout <<“ 该图书不存在” << endl; break; } b->delbook(); break; case '4': cout << “ 读入图书编号:”< cin >> bookid; b=query(bookid); if(b==NULL) { cout <<“ 该图书不存在”<< endl; break; } b->disp(); break; case '5': disp(); break; case '6': clear(); break; default:cout<<“输入错误,请从新输入:”; } } } cout << “输入图书编号:”< cin >> bookid; cout << “输入图书书名:”< cin >> bname; addbook(bookid,bname); break; case '2': cout << “输入图书编号:”< cin >> bookid; b=query(bookid); if(b==NULL) { cout << “ 该图书不存在 ”< break; } cout << “输入新的书名:”< cin >> bname; b->setname(bname); break; case '3': cout <<“ 读入图书编号:”< cin >> bookid; b=query(bookid); if(b==NULL) { cout <<“ 该图书不存在” << endl; break; } b->delbook(); break; case '4': cout << “ 读入图书编号:”< cin >> bookid; b=query(bookid); if(b==NULL) { cout <<“ 该图书不存在”<< endl; break; } b->disp(); break; case '5': disp(); break; case '6': clear(); break; default:cout<<“输入错误,请从新输入:”; } } 3、系统实现 3.1 编码 3.1.2 主函数main()include #include #include //输入/输出文件流类 #include using namespace std; //最多的读者 const int Maxr=100; //最多的图书 const int Maxb=100; //每位读者最多借五本书 const int Maxbor=5; //图书库类,实现对图书的维护,查找,删除等 class BDatabase { private: //图书记录指针 int top; //图书记录 Book book[Maxb]; public: //构造函数,将book.txt读到book[]中 BDatabase() { Book b; top=-1; fstream file(“book.txt”,ios::in); while(1) { file.read((char *)&b,sizeof(b)); if(!file)break; top++; book[top]=b; } file.close(); } //全删 void clear() { top=-1; } //增加图书 int addbook(int n,char *na) { Book *p=query(n); if(NULL==p) { top++; book[top].addbook(n,na); return 1; } return 0; } //查找图书 Book *query(int bookid) { for(int i=0;i<=top;i++) if(book[i].getno()==bookid &&book[i].gettag()==0) { return &book[i]; } return NULL; } //图书库维护 void bookdata(); void disp() { for(int i=0;i<=top;i++) if(book[i].gettag()==0) book[i].disp(); } //析构函数,将book[]写到book.txt文件中 ~BDatabase() { fstream file(“book.txt”,ios::out); for(int i=0;i<=top;i++) if(book[i].gettag()==0) file.write((char *)&book[i],sizeof(book[i])); file.close(); } }; void BDatabase::bookdata() { char choice; char bname[40]; int bookid; Book *b; while(choice!='0') { cout <<“nnnttt图 书 维 护 ”< cout<<“tt1 新 增n tt2 更 改ntt3 删 除ntt4 查 找ntt5 显 示ntt6 全 删ntt0 退 出”< cin >> choice; switch(choice) { case '1': cout << “输入图书编号:”< cin >> bookid; cout << “输入图书书名:”< cin >> bname; addbook(bookid,bname); break; case '2': cout << “输入图书编号:”< cin >> bookid; b=query(bookid); if(b==NULL) { cout << “ 该图书不存在 ”< break; } cout << “输入新的书名:”< cin >> bname; b->setname(bname); break; case '3': cout <<“ 读入图书编号:”< cin >> bookid; b=query(bookid); if(b==NULL) { cout <<“ 该图书不存在” << endl; break; } b->delbook(); break; case '4': cout << “ 读入图书编号:”< cin >> bookid; b=query(bookid); if(b==NULL) { cout <<“ 该图书不存在”<< endl; break; } b->disp(); break; case '5': disp(); break; case '6': clear(); break; default:cout<<“输入错误,请从新输入:”; } } } //main()函数的实现,程序的主界面的引导 int main() { char choice; int bookid,readerid; RDatabase ReaderDB; Reader *r; BDatabase BookDB; Book *b; while(choice!='0') { cout < cout <<“ttt1 借 书nnttt2 还 书 nnttt3 图 书 维 护nnttt4 读 者 维 护nnttt0 离 开”< cin >> choice; switch(choice) { case '1': cout <<“ 借书 读者编号:”; cin >>readerid; cout <<“ 图书编号: ”; cin >>bookid; //按编号查找 r=ReaderDB.query(readerid); if(NULL==r) { cout <<“ 不存在该读者,不能借书”<< endl; break; } b=BookDB.query(bookid); if(b==NULL) { cout <<“ 不存在该图书,不能借书”<< endl; break; } if(b->borrowbook()==0) { cout << “ 该图书已借出,不能借书”<< endl; break; } r->borrowbook(b->getno()); break; case '2': cout<<“还书n 读者编号:”; cin >>readerid; cout << “ 图书编号:”; cin >>bookid; r=ReaderDB.query(readerid); if(r==NULL) { cout <<“ 不存在该读者,不能还书” << endl; break; } b=BookDB.query(bookid); if(b==NULL) { cout <<“ 不存在该图书,不能还书” < break; } b->retbook(); r->retbook(b->getno()); break; case '3': BookDB.bookdata(); break; case '4': ReaderDB.readerdata(); break; default:cout<<“输入错误,请从新输入:”; 4、系统维护 经测试与调试确认软件无错时,开发就告一段落,这时可以交付软件供用户使用,但是在软件的使用过程中还会面临更加漫长的工作,即软件维护。一般维护的工作有:更改使用中发现的错误;为适应实际环境而对程序进行修改;为满足新的需求而对程序作必要的改进等等。 5、归纳总结 5.1 开发经验 通过对本题目的开发,体会到要掌握以下几点内容。 大程序的设计风格。按“自顶向下,逐步细化,模块化”的方法进行程序设计。 编写主函数,并进行测试与调试。当被调函数又需要调用其他函数时,也要遵循逐步细化的原则。C语言提供丰富的库函数,编程序时要善于使用库函数,避免不必要的劳动。 定义函数时,应选好参数的个数和数据类型。 文件使用方法。文件使用完毕后应及时关闭。 5.2 实训中遇到的问题及解决方法 在实训过程中,我遇到许多的问题,比如有些语句有语法错误,表达式不正确,或缺少}或;等。或者是没有宏定义,申明某些变量。这些都比较容易解决。通过查阅课本和请教同学,在经过WIN-TV编译,知道哪有错误就改一下就行。比较严重的是,我的代码在求解平均成绩和总分时没有录入,且乱码。自已改了很久,也在网上查询但是都不行。最后在老师的帮助下及查阅有关资料,把代码改出来了。 5.3 设计中尚存的不足之处 关于这次的程序,也有挺多不足的地方。首先,我觉得程序还不够完善,比如没有排序前和排序后的学生记录输出结果显示和有些程序功能没有满足所给题目要求及好几项都没有显示出学生具体的信息,甚至有些地方有点乱;其次,有些地方好像功能有点重复了,且编写的代码有重复;最后,就是该程序界面不够美观大方,有些文件不能链接。 5.4 感想和心得体会 通过这次实训,我感触甚深,要把所学的理论知识运用于解决实际问题不仅要付出艰辛的劳动,还得要有科学的方法和坚持不懈的努力。加上我们只是学了一个学期的c语言,我们所学的知识还不足以独立编写程序代码。但是我认为只要我们认真的去学去做,我们会受益非浅。这次实训让我进一步理解了“编程是什么”,“如何去编程”,“编程的目的又是什么”,„„发现自己的知识竟是如此贫乏,顿时感到了压力的存在,从而也激发了我的学习热情。它会成为我今后不断进取、永不懈怠的动力。 在整个实训过程中,老师给了我很大的帮助,使我由不了解怎样运用链表到逐渐懂得链表的结构及初步掌握链表结构。还重新复习了一些语句的使用,比如for(0;switch();if….elser();结构体的使用;枚举等。而且我能够坚持虚心的向老师以及同学请教问题。它使我明白了虚心好学的重要性,更让我懂得了如何跟老师同学去相处、去沟通。没有老师和同学们的无私帮助,我不可能圆满完成这次实训任务。非常感谢帮助过我的所有老师和同学们,在此,谨向他们一并表示感谢!我开始喜欢这个程序设计了,尤其觉得它是很有挑战性的,是对知识点扎实程度的考察,也是对个人能力的考察,还是对个人化毅力的考验。它让我明白做任何事都不应该轻易放弃。这样的课程设计,既有利于教学,又可以教会学生书本以外的很多知识。现在我对它越来越感兴趣,今后我会更加关注C语言程序,把C语言学好。希望老师以后多多指导,给予一定的帮助! 数据库设计实例 教务管理系统 数据库实验七 数据库设计 题目要求: 设计一个教务管理系统。要求管理包括:学生的档案,学生选课的情况,学生每学期的综合测评,教师档案,教师工作量等等。具体考核方法根据自己了解的实际情况处理。 假设此次设计的教务系统是整个学生管理系统数据库中的一部分,整个系统至少还包括学籍管理等其他子系统。 在初期设计时,先关注与教务系统有关的数据。在完成对教务管理系统的建模后再对整个系统进行合并,总终得到整个系统的设计方案。 一、需求分析 1、根据分析可以画出该教务管理系统的数据流图: 学生 选课 上课 考试 测评 选课单 允许考试 成绩单 老师档案 课程简介 教室安排 试卷 考场安排 测评报告单 学生名单 教师 选定教材 申报 课表 2、数据字典 数据结构:学生 含义说明:是教务管理系统的一个核心数据结构,定义了学生的有关信息 组成:学号、姓名 数据项:学号 含义说明:唯一标识每一个学生 别名:学生编号 类型:字符型 长度:9位 取值范围:190000000 – 999999999 取值含义:前四位表明学生所在年级,后五位安顺序编号 数据项:姓名 含义说明:表示学生的姓名 类型:字符型 长度:10位 取值范围:任意字符 数据结构:教师 含义说明:教务管理系统的核心数据结构之一,定义了教师的有关信息 组成:教师号,教师姓名 数据项:教师号 含义说明:教师的编号 类型:字符型 长度:5位 取值范围:10000 – 99999 数据项:教师姓名 含义说明:教师的姓名 类型:字符型 长度:10位 取值范围:任意合法的字符 数据结构:课程 含义说明:教务管理系统的核心数据结构之一,定义了课程的有关信息 组成:课程号,课程名,课程描述,教师,教室,教科书,学分 数据项:课程号 含义说明:课程的编号 类型:字符型 长度:4 取值范围:0001 – 9999 数据项:课序号 含义说明:对于同一课程,由不同老师教授,用课序号来区分 类型:字符型 长度:2 取值范围:01 – 99 数据项:课程名 含义说明:课程的名称 类型:字符型 长度:10 取值范围:任意合法的字符 数据项:课程描述 含义说明:课程内容的基本描述 类型:字符型 长度:200 取值范围:任意合法字符 数据项:教科书 含义说明:课程所用的教科书 类型:字符型 长度:20 取值范围:任意合法字符 数据项:学分 含义说明:课程的学分 类型:整型 长度:1 取值范围:1-9 数据结构:教室 含义说明:上课所用的教室 组成:教室编号,教室地址,教室容量 数据项:教室编号 含义说明:教室的编号 类型:字符 长度:5 取值范围:00001-99999 数据项:教室地址 含义说明:标明教室的地址 类型:字符 长度:30 取值范围:任意合法的字符 数据项:教室容量 含义说明:教室的容纳学生的数量 类型:整型 取值范围:正整数 数据结构:选课记录 含义说明:纪录学生选课的纪录 组成:学生,课程,成绩 数据项:成绩 含义说明:选课学生本学期的成绩 类型:浮点数 范围:0.0 – 100.0 处理过程:分配教室 说明:为所有课程分配上课教室 输入:课程,教室 输出:教室安排 处理:学期课程决定后,要为每个课程安排上课地点,要求上课的地点不能冲突且上课人数不能超过教室容量。 处理过程:分配考场 说明:在考试日期,为所有课程分配考场 输入:课程,教室 输出:考场安排 处理:为每个课程安排考场,考试时间和地点不能冲突且考试人数不能超过考场容量。 数据存储:成绩单 说明:记录学生本学期所有课程成绩 流入数据流:学生所有的选课记录 流出数据流:学生的成绩单 数据量:由学生的人数决定 存取方式:随机存取 二、概念结构设计 1、根据需求分析画出E-R图: 选修 学生 教师 课程 m n 讲授 1 n 教科书 n 成绩 教室 开设 1 n 2、根据E-R图写出各个实体的属性描述 学生:{学号,姓名} 课程:{课程号,课程名,课程描述,学分} 教师:{教师号,教师名,课程数} 教室:{教室编号,地址,容量} 3、视图的集成 假设在学生管理系统的学籍管理系统中存在另一个学生实体,其中还包括以下信息:性别,所属专业,所属班级。为了使两个实体保持一致,对两个实体取并集得到新的学生实体: 学生:{学号,姓名,性别,专业,班级} 三、逻辑结构设计 1、由E-R图向数据模型的转换 一个实体型转换为一个关系模式。实体的属性就是关系的属性。实体的码就是关系的码。所以,E-R图中的属性描述可直接转换为相应的关系模式。 2、对于剩余的一对多和多对多联系可以如下表示 学生-课程:{学号,课程号,课序号,成绩} 课程-教师:{课程号,课序号,教师号} 课程-教科书:{课程号,课序号,教科书} 教室-课程:{教室号,时间,课程号,课序号} 其中 课程-教师 与 课程-教科书 具有相同的主码,可以合并成一个关系 教学:{课程号,课序号,教师号,教科书} 最后得到的关系模式为 学生:{学号,姓名,性别,专业,班级} 课程:{课程号,课程名,课程描述,学分} 教师:{教师号,教师名,课程数} 教室:{教室号,地址,容量} 学生-课程:{学号,课程号,课序号,成绩} 教学:{课程号,课序号,教师号,教科书} 教室-课程:{教室号,时间,课程号,课序号} 3、用户外模式 根据需求,为计算综合测评增加一个外模式,因为综合测评只在学期末进行,查询次数不多,所以没有必要用冗余的方法来提高查询效率,只需要建立一个外模式视图即可。 测评{学号,学生姓名,平均成绩} 4、根据设计写出相应的SQL语句: CREATE TABLE student(Sno VARCHAR(9) CONSTRAINT pk_student PRIMARY KEY,Sname VARCHAR(10)NOT NULL,Sex VARCHAR(1) NOT NULL,Major VARCHAR(10) NOT NULL,Class VARCHAR(10) NOT NULL,CHECK (Sex = 'f' OR Sex = 'm')) CREATE TABLE course(Cno VARCHAR(4) CONSTRAINT pk_course PRIMARY KEY,Cname VARCHAR(10) NOT NULL,Describe VARCHAR(200),Mark INTEGER) CREATE TABLE teacher(Tno VARCHAR(5) CONSTRAINT teacher_pk PRIMARY KEY,Tname VARCHAR(10) NOT NULL,Ccnt INTEGER NOT NULL DEFAULT 0) CREATE TABLE classroom(Rno VARCHAR(5)CONSTRAINT pk_classroom PRIMARY KEY,Locate VARCHAR(30)NOT NULL,Cap INTEGER CHECK (Cap > 0)) CREATE TABLE tech(Cno VARCHAR(4)NOT NULL CONSTRAINT fk_course_cno FOREIGN KEY REFERENCES course(Cno)ON UPDATE CASCADE --级联更新 ON DELETE CASCADE,--级联删除 SCno VARCHAR(2)NOT NULL,Tno VARCHAR(5)CONSTRAINT fk_teacher_tno FOREIGN KEY REFERENCES teacher(Tno) ON UPDATE CASCADE ON DELETE CASCADE,Book VARCHAR(20) CONSTRAINT pk_tech PRIMARY KEY(Cno,SCno)) CREATE TABLE SC(Sno VARCHAR(9)NOT NULL CONSTRAINT fk_student_sno FOREIGN KEY REFERENCES student(Sno) ON UPDATE CASCADE ON DELETE CASCADE,Cno VARCHAR(4)NOT NULL CONSTRAINT fk_sc_course_cno FOREIGN KEY REFERENCES course(Cno) ON UPDATE CASCADE ON DELETE CASCADE,SCno VARCHAR(2)NOT NULL,Score FLOAT CONSTRAINT pk_sc PRIMARY KEY(Sno,Cno,SCno)) CREATE TABLE RC(Rno VARCHAR(5)CONSTRAINT fk_classroom_rno FOREIGN KEY REFERENCES classroom(Rno) ON UPDATE CASCADE ON DELETE CASCADE,Time DATETIME,Cno VARCHAR(4)NOT NULL CONSTRAINT fk_rc_course_cno FOREIGN KEY REFERENCES course(Cno) ON UPDATE CASCADE ON DELETE CASCADE,SCno VARCHAR(2)NOT NULL CONSTRAINT pk_rc PRIMARY KEY(Rno,Time)) 为进行综合测评增加一个外模式 CREATE VIEW assess AS SELECT SC.sno, sname, AVG(score)as average FROM SC,Student where SC.sno = student.sno GROUP BY SC.sno,sname 为了符合数据的参照完整性约束,避免学生选课的时候选择一个不存在的课程号-课序号组,增加一个外键约束。ALTER TABLE sc ADD CONSTRAINT fk_sc_tech FOREIGN KEY(Cno,SCno)REFERENCES tech(Cno,SCno) ON UPDATE CASCADE ON DELETE CASCADE 为了在插入一个新课程时能级联更新教师的工作量,增加一个触发器。此任务也可以通过建立一个外模式视图来动态统计,为了练习的目的这里采用了触发器 CREATE TRIGGER workcnter On tech AFTER INSERT ,UPDATE, DELETE AS BEGIN DECLARE @T VARCHAR(5) IF EXISTS (SELECT TOP 1 Tno FROM INSERTED) BEGIN SET @T =(SELECT TOP 1 Tno FROM INSERTED) UPDATE teacher SET Ccnt = Ccnt + 1 WHERE Tno = @T END IF EXISTS (SELECT TOP 1 Tno FROM DELETED) BEGIN SET @T =(SELECT TOP 1 Tno FROM DELETED) UPDATE teacher SET Ccnt = Ccnt1 WHERE Tno = @T END END 关于课程容量:如何保证选课的学生数量不超过教室的容量? 初步解决办法是:在学生选课时建立暂时不考虑容量问题,都加渗透一个临时的SC表中。然后,在选课结束后将未超额的记录直接加渗透SC表,超额的课程进行抽签,将命中部分学生的选课记录插入SC表,直到人数符合课程容量的要求为止。 抽签的功能较适合用顶层的高级语言来实现。在选课结束后,选超额课程的学生需登陆选课系统进行抽签,抽签的过程可以使用概率算法,如果抽中,系统再将选课记录插入SC表,否则就从临时表中删除。所以,在数据库系统中,没有对SC表的插渗入渗出操作进行约束。 本文来自CSDN博客,转载请标明出处: http://blog.csdn.net/lesky/archive/2006/12/25/1460 966.aspx 数据库设计---教务管理系统 2009年12月03日 星期四 11:04 P.M.题目要求: 设计一个教务管理系统。要求管理包括:学生的档案,学生选课的情况,学生每学期的综合测评,教师档案,教师工作量等等。具体考核方法根据自己了解的实际情况处理。 假设此次设计的教务系统是整个学生管理系统数据库中的一部分,整个系统至少还包括学籍管理等其他子系统。 在初期设计时,先关注与教务系统有关的数据。在完成对教务管理系统的建模后再对整个系统进行合并,总终得到整个系统的设计方案。 一、需求分析 1、根据分析可以画出该教务管理系统的数据流图: 学生 选课 上课 考试 测评 选课单 允许考试 成绩单 老师档案 课程简介 教室安排 试卷 考场安排 测评报告单 学生名单 教师 选定教材 申报 课表 2、数据字典 数据结构:学生 含义说明:是教务管理系统的一个核心数据结构,定义了学生的有关信息 组成:学号、姓名 数据项:学号 含义说明:唯一标识每一个学生 别名:学生编号 类型:字符型 长度:9位 取值范围:190000000 – 999999999 取值含义:前四位表明学生所在年级,后五位安顺序编号 数据项:姓名 含义说明:表示学生的姓名 类型:字符型 长度:10位 取值范围:任意字符 数据结构:教师 含义说明:教务管理系统的核心数据结构之一,定义了教师的有关信息 组成:教师号,教师姓名 数据项:教师号 含义说明:教师的编号 类型:字符型 长度:5位 取值范围:10000 – 99999 数据项:教师姓名 含义说明:教师的姓名 类型:字符型 长度:10位 取值范围:任意合法的字符 数据结构:课程 含义说明:教务管理系统的核心数据结构之一,定义了课程的有关信息 组成:课程号,课程名,课程描述,教师,教室,教科书,学分 数据项:课程号 含义说明:课程的编号 类型:字符型 长度:4 取值范围:0001 – 9999 数据项:课序号 含义说明:对于同一课程,由不同老师教授,用课序号来区分 类型:字符型 长度:2 取值范围:01 – 99 数据项:课程名 含义说明:课程的名称 类型:字符型 长度:10 取值范围:任意合法的字符 数据项:课程描述 含义说明:课程内容的基本描述 类型:字符型 长度:200 取值范围:任意合法字符 数据项:教科书 含义说明:课程所用的教科书 类型:字符型 长度:20 取值范围:任意合法字符 数据项:学分 含义说明:课程的学分 类型:整型 长度:1 取值范围:1-9 数据结构:教室 含义说明:上课所用的教室 组成:教室编号,教室地址,教室容量 数据项:教室编号 含义说明:教室的编号 类型:字符 长度:5 取值范围:00001-99999 数据项:教室地址 含义说明:标明教室的地址 类型:字符 长度:30 取值范围:任意合法的字符 数据项:教室容量 含义说明:教室的容纳学生的数量 类型:整型 取值范围:正整数 数据结构:选课记录 含义说明:纪录学生选课的纪录 组成:学生,课程,成绩 数据项:成绩 含义说明:选课学生本学期的成绩 类型:浮点数 范围:0.0 – 100.0 处理过程:分配教室 说明:为所有课程分配上课教室 输入:课程,教室 输出:教室安排 处理:学期课程决定后,要为每个课程安排上课地点,要求上课的地点不能冲突且上课人数不能超过教室容量。 处理过程:分配考场 说明:在考试日期,为所有课程分配考场 输入:课程,教室 输出:考场安排 处理:为每个课程安排考场,考试时间和地点不能冲突且考试人数不能超过考场容量。 数据存储:成绩单 说明:记录学生本学期所有课程成绩 流入数据流:学生所有的选课记录 流出数据流:学生的成绩单 数据量:由学生的人数决定 存取方式:随机存取 二、概念结构设计 1、根据需求分析画出E-R图: 选修 学生 教师 课程 m n 讲授 n 教科书 n 成绩 教室 开设 n 2、根据E-R图写出各个实体的属性描述 学生:{学号,姓名} 课程:{课程号,课程名,课程描述,学分} 教师:{教师号,教师名,课程数} 教室:{教室编号,地址,容量} 3、视图的集成 假设在学生管理系统的学籍管理系统中存在另一个学生实体,其中还包括以下信息:性别,所属专业,所属班级。为了使两个实体保持一致,对两个实体取并集得到新的学生实体: 学生:{学号,姓名,性别,专业,班级} 三、逻辑结构设计 1、由E-R图向数据模型的转换 一个实体型转换为一个关系模式。实体的属性就是关系的属性。实体的码就是关系的码。所以,E-R图中的属性描述可直接转换为相应的关系模式。 2、对于剩余的一对多和多对多联系可以如下表示 学生-课程:{学号,课程号,课序号,成绩} 课程-教师:{课程号,课序号,教师号} 课程-教科书:{课程号,课序号,教科书} 教室-课程:{教室号,时间,课程号,课序号} 其中 课程-教师 与 课程-教科书 具有相同的主码,可以合并成一个关系 教学:{课程号,课序号,教师号,教科书} 最后得到的关系模式为 学生:{学号,姓名,性别,专业,班级} 课程:{课程号,课程名,课程描述,学分} 教师:{教师号,教师名,课程数} 教室:{教室号,地址,容量} 学生-课程:{学号,课程号,课序号,成绩} 教学:{课程号,课序号,教师号,教科书} 教室-课程:{教室号,时间,课程号,课序号} 3、用户外模式 根据需求,为计算综合测评增加一个外模式,因为综合测评只在学期末进行,查询次数不多,所以没有必要用冗余的方法来提高查询效率,只需要建立一个外模式视图即可。测评{学号,学生姓名,平均成绩} 4、根据设计写出相应的SQL语句: CREATE TABLE student(Sno VARCHAR(9)CONSTRAINT pk_student PRIMARY KEY, Sname VARCHAR(10)NOT NULL, Sex VARCHAR(1)NOT NULL, Major VARCHAR(10)NOT NULL, Class VARCHAR(10)NOT NULL, CHECK(Sex = 'f' OR Sex = 'm')) CREATE TABLE course(Cno VARCHAR(4)CONSTRAINT pk_course PRIMARY KEY, Cname VARCHAR(10)NOT NULL, Describe VARCHAR(200), Mark INTEGER) CREATE TABLE teacher(Tno VARCHAR(5)CONSTRAINT teacher_pk PRIMARY KEY, Tname VARCHAR(10)NOT NULL,Ccnt INTEGER NOT NULL DEFAULT 0) CREATE TABLE classroom(Rno VARCHAR(5)CONSTRAINT pk_classroom PRIMARY KEY, Locate VARCHAR(30)NOT NULL, Cap INTEGER CHECK(Cap > 0)) CREATE TABLE tech(Cno VARCHAR(4)NOT NULL CONSTRAINT fk_course_cno FOREIGN KEY REFERENCES course(Cno)ON UPDATE CASCADE--级联更新 ON DELETE CASCADE,--级联删除 SCno VARCHAR(2)NOT NULL,Tno VARCHAR(5)CONSTRAINT fk_teacher_tno FOREIGN KEY REFERENCES teacher(Tno)ON UPDATE CASCADE ON DELETE CASCADE, Book VARCHAR(20) CONSTRAINT pk_tech PRIMARY KEY(Cno,SCno)) CREATE TABLE SC(Sno VARCHAR(9)NOT NULL CONSTRAINT fk_student_sno FOREIGN KEY REFERENCES student(Sno)ON UPDATE CASCADE ON DELETE CASCADE,Cno VARCHAR(4)NOT NULL CONSTRAINT fk_sc_course_cno FOREIGN KEY REFERENCES course(Cno)ON UPDATE CASCADE ON DELETE CASCADE, SCno VARCHAR(2)NOT NULL, Score FLOAT CONSTRAINT pk_sc PRIMARY KEY(Sno,Cno,SCno)) CREATE TABLE RC(Rno VARCHAR(5)CONSTRAINT fk_classroom_rno FOREIGN KEY REFERENCES classroom(Rno)ON UPDATE CASCADE ON DELETE CASCADE, Time DATETIME,Cno VARCHAR(4)NOT NULL CONSTRAINT fk_rc_course_cno FOREIGN KEY REFERENCES course(Cno)ON UPDATE CASCADE ON DELETE CASCADE, SCno VARCHAR(2)NOT NULL CONSTRAINT pk_rc PRIMARY KEY(Rno,Time)) 为进行综合测评增加一个外模式 CREATE VIEW assess AS SELECT SC.sno, sname, AVG(score)as average FROM SC,Student where SC.sno = student.sno GROUP BY SC.sno,sname 为了符合数据的参照完整性约束,避免学生选课的时候选择一个不存在的课程号-课序号组,增加一个外键约束。ALTER TABLE sc ADD CONSTRAINT fk_sc_tech FOREIGN KEY(Cno,SCno)REFERENCES tech(Cno,SCno)ON UPDATE CASCADE ON DELETE CASCADE 为了在插入一个新课程时能级联更新教师的工作量,增加一个触发器。此任务也可以通过建立一个外模式视图来动态统计,为了练习的目的这里采用了触发器 CREATE TRIGGER workcnter On tech AFTER INSERT ,UPDATE, DELETE AS BEGIN DECLARE @T VARCHAR(5)IF EXISTS(SELECT TOP 1 Tno FROM INSERTED)BEGIN SET @T =(SELECT TOP 1 Tno FROM INSERTED)UPDATE teacher SET Ccnt = Ccnt + 1 WHERE Tno = @T END IF EXISTS(SELECT TOP 1 Tno FROM DELETED)BEGIN SET @T =(SELECT TOP 1 Tno FROM DELETED)UPDATE teacher SET Ccnt = Ccnt-1 WHERE Tno = @T END END 关于课程容量:如何保证选课的学生数量不超过教室的容量? 初步解决办法是:在学生选课时建立暂时不考虑容量问题,都加入一个临时的SC表中。然后,在选课结束后将未超额的记录直接加入SC表,超额的课程进行抽签,将命中部分学生的选课记录插入SC表,直到人数符合课程容量的要求为止。 抽签的功能较适合用顶层的高级语言来实现。在选课结束后,选超额课程的学生需登陆选课系统进行抽签,抽签的过程可以使用概率算法,如果抽中,系统再将选课记录插入SC表,否则就从临时表中删除。 所以,在数据库系统中,没有对SC表的插入操作进行约束。 分析IBM的停车场智能泊车分析系统 来源:停车场 http:// | 发布时间:2011-10-9 | 浏 览次数:4 IBM推出停车场智能泊车分析系统,帮助城市消除停车拥堵现象同时征收到更多的停车费,它也能帮助司机更容易地在拥挤的闹市区找到停车位。智能泊车(Smarter Parking)系统结合IBM的数据分析能力和Streetline在停车感测器与软件上的创新技术。安置在停车场的Streetline省电感测器,监测是否有车子在场,然后把信息即时传到城市网络与Android或iOS应用程序。城市交通管理员可以利用这些数据追踪流量或设定停车费率,而驾驶员可以把车子停到空位。 IBM针对北京、巴黎与洛杉矶等20座城市的调查,证实了驾驶者一直以来的心声:停车真痛苦。在受访的驾驶中,每10人就有6人说,过去一年他们找车位找得很挫折,有时候会放弃并改变计划。逾1/4受访者说,他们曾因为停车位跟别人起口角。IBM表示,约30%的城市车流量,是人们开车在路上乱转,找地方停车。淄博黑牛机电设备科技有限公司坐落于山东省淄博市高新技术开发区,现有员工100多人。是集开发、设计、生产于一体的专业厂家,主要生产电动门、移动厕所、公共厕所以及各种环保岗亭、停车场、电动伸缩门、高速公路设施及小区智能管理系统。 数十年来,我厂以优质的产品,良好技术服务及诚心的态度赢得了广大客户的信赖!竭诚欢迎新老朋友光临惠顾,携手共创更加美好的明天!文章来源:淄博黑牛机电设备http://转载请保留!第二篇:C++程序设计—电话簿管理系统
第三篇:C语言程序设计图书管理系统
第四篇:数据库程序设计---教务辅助管理系统
第五篇:分析IBM的停车场智能泊车分析系统