第一篇:C++课程设计电话簿管理
C++课程设计
————简单电话簿管理
报告内容: 一.程序功能简介 二.课程设计要求 三.课程设计说明 四.参考数据结构 五.具体功能及实现六.源程序及注释 七.感想与心得
学号:050930109 姓名:陈浩 指导老师:臧洌 日期:2010年6月20日
一.程序功能简介
一个基本的电话簿管理程序,具有插入、删除、显示、修改和查询联系人电话码的功能。主菜单如右图所示,每个菜单项功能如下:
1.增加记录菜单:请输入用户姓名,如果该用户已经存在则添加失败,否则,输入用户的电话号码,进行添加。
2.修改某条记录:请输入用户姓名,如果没有该用户显示“ 该用户不存在”信息,否则,输出原电话号码,然后输入新的电话号码,进行修改。3.删除记录:
输入用户姓名,进行删除(删除时要进行确认)。4.查询:输入用户姓名,进行查找。
5.排序:根据子菜单,选择不同的排序方式。6.显示:逐屏显示(每屏显示10条记录)。7.全删:进行全部删除(要确认)。
二.课程设计要求
请选择以下功能 1-增加记录 2-修改记录 3-删除记录
4-查找(按姓名)5-排序 6-显示记录
1.用汉化菜单实现。
2.提供按姓名查询电话号码的功能。
3.显示功能(提供逐屏显示的功能,每屏显示10条记录)。4.删除和修改时要进行确认。
5.将电话簿记录以文件的形式存在磁盘上;每次操作时将电话簿调出,操作完毕后存盘。
三.课程设计说明
1.程序采用数组数据结构实现。2.用类来实现数据的封装。
四.参考数据结构
1.“电话簿”称为用户信息表,用数组实现。用户信息表由若干用户信息构成,每个用户信息是一个数组元素。
2.“user.txt”是一个文件,用于保存“用户信息表”中的信息。当系统启动时,从该文件中读入信息,当退出系统时,将“用户信息表”中的信息写到该文件中。该文件中信息存放形式如下:
ZhangHong 5221369 LiLi 84891112
ZhaoQiang 5221498
其中 name(姓名)占20列 phone_num(电话号码)占12列
五.具体功能及实现
定义Fphone类,通过其私有成员数组name[20]和phone[12]分别记录用户姓名与电话号码,定义UserDatabase类记录用户信息,通过公有成员函数实现对数据的操作。
六.源程序及注释
#include
//用户信息类的定义 {
char name[M];
// 姓名
char phone_num[N];
//电话号码 public: Fphone(char *na=“",char *ph=”“){ strcpy(name,na);
strcpy(phone_num,ph);} char*getname();
//获取姓名
char*getphone_num();
//获取电话号码
void setname(char*a);
//设置姓名
void setphone_num(char*a);//设置电话号码
void disp();
//显示用户信息 };char *Fphone::getname()
{ return name;} char *Fphone::getphone_num(){ return(phone_num);} void Fphone::setname(char *a){ strcpy(name,a);
} void Fphone::setphone_num(char*a){ strcpy(phone_num,a);} void Fphone::disp(){ cout<<”姓名:“<
//用户信息表中的元素个数,即当前记录总数
int Maxu;
//最多的用户
Fphone *user;
//指向用户信息表的指针
public: UserDatabase()
//构造函数,初始化用户信息表,将user.txt文件中数据读到User[]中
{ nElem=0;
Maxu=50;
user=new Fphone[Maxu];
fstream in;
in.open(”user.txt“,ios::in|ios::nocreate);//打开文件
for(int i=0;(!in.eof());i++)
{ in>>user[i].getname();in>>user[i].getphone_num();
nElem++;
}
in.close();}
~UserDatabase()
//析构函数,将user[]写入user.txt文件中
{ fstream out;
Fphone *p=NULL;
p=user;
out.open(”user.txt“,ios::out,filebuf::sh_none);
for(int i=0;i { out< <<((p+i)->getphone_num())< }delete []user; out.close();} void clear() //删除所有用户信息 { char ord; cout<<”确定删除吗?(选择:[y]是;[n]否)aa“< do { cin>>ord; if(ord=='N'||ord=='n')return; else if(ord=='Y'||ord=='y') { delete[Maxu]user; } user=0;cout<<”删除成功啦!“< user->setname(na); user->setphone_num(ph_num); } else if(nElem { if(strcmp((user+i)->getname(),na)>0) {(user+i+1)->setname(((user+i)->getname())); (user+i+1)->setphone_num(((user+i)->getphone_num())); } else break; } (user+i+1)->setname(na); (user+i+1)->setphone_num(ph_num); nElem++;} else cout <<”空间不足,无法添加!“< //返回user指针 { return(user);} void delete_record(Fphone *p,int k) //删除用户信息 { char con;cout<<”确认删除?(Y/N)“;cin>>con;if(con=='N'||con=='n')return;else if(con=='Y'||con=='y'){ for(int i=k;i { user[i]=user[i+1];} nElem--; cout<<”已删除!“< return;} else { cout<<”输入错误!“< system(”pause“); return;} } void modify_record(Fphone *p,char*ph_num)//修改用户信息 { p->setphone_num(ph_num);} Fphone *query(char *na) //按姓名查找 顺序查找,这里也可以用折半 { Fphone *p=user; int i=0; while(1) { if(strcmp(p->getname(),na)==0) return p; p++; if(i++==nElem) break;} return NULL;} void sorta_name()//按姓名升序排序 插入排序法 { Fphone temp;int i,j;for(i=1;i for(j=i-1;j>=0&&(strcmp(temp.getname(),user[j].getname())<0);j--) { strcpy(user[j+1].getname(),user[j].getname()); strcpy(user[j+1].getphone_num(),user[j].getphone_num()); } strcpy(user[j+1].getname(),temp.getname()); strcpy(user[j+1].getphone_num(),temp.getphone_num());} } void sorta_phonenum()//按电话号码升序排序 选择排序法 { int i,j,p;Fphone temp;for(i=0;i for(j=i+1;j if(strcmp(user[j].getphone_num(),user[p].getphone_num())<0)p=j; if(p!=i) { strcpy(temp.getname(),user[p].getname()); strcpy(temp.getphone_num(),user[p].getphone_num()); strcpy(user[p].getname(),user[i].getname()); strcpy(user[p].getphone_num(),user[i].getphone_num()); strcpy(user[i].getname(),temp.getname()); strcpy(user[i].getphone_num(),temp.getphone_num()); } } } void sort_name()//按姓名降序排序,将排成升序的对象数组逆向放置 { Fphone temp;int i,m=(nElem+1)/2;for(i=0;i strcpy(temp.getphone_num(),user[i].getphone_num()); strcpy(user[i].getname(),user[nElem-i-1].getname()); strcpy(user[i].getphone_num(),user[nElem-i-1].getphone_num()); strcpy(user[nElem-i-1].getname(),temp.getname()); strcpy(user[nElem-i-1].getphone_num(),temp.getphone_num());} } void sort_phonenum()//按电话号码降序排序 冒泡排序法 { Fphone temp;int i,m=(nElem+1)/2;for(i=0;i strcpy(temp.getphone_num(),user[i].getphone_num()); strcpy(user[i].getname(),user[nElem-i-1].getname()); strcpy(user[i].getphone_num(),user[nElem-i-1].getphone_num()); strcpy(user[nElem-i-1].getname(),temp.getname()); strcpy(user[nElem-i-1].getphone_num(),temp.getphone_num());} } void disp(){ int i,n=0;cout< cout< < n++; if(n%10==0) { system(”pause“); system(”cls“); } } cout< 请选择以下功能:“< 1-增加记录“< 2-修改记录“< 3-删除记录“< 4-查找(按姓名)“< 5-排序“< 6-显示记录“< 7-全删“< 0-退出“< 输入选择:“< “< “< 欢迎使用电话簿管理系统 “< 祝您使用愉快 “< “< system(”cls“); menu(); int k; cin>>k; switch(k) { case 1: { system(”cls“) cout<<”*****************************************“< cout<<” 增加记录 “< Fphone *t=NULL; char w; do { cout<<”请输入您要增加的用户的姓名“; cin>>na; t=(s.query(na)); if(t) { cout<<”用户已经存在,添加失败!!“< else { cout<<”请输入用户的电话号码“; cin>>ph_num; s.add_record(na,ph_num);cout<<”您添加的信息为:“;cout<<”姓名:“< } cout<<”是否继续?(Y or N)“< cin>>w;} while(w=='Y');break;} case 2: { system(”cls“); cout<<”***************************************“< 修改记录 “< char na[M],ph_num[N]; Fphone *t=NULL; char w; do { cout<<”请输入您要修改的用户的姓名“; cin>>na; t=s.query(na); if(!t) cout<<”没有该用户!“< else { cout<<”该用户原号码为:“< cout<<”请输入新的电话号码“; cin>>ph_num; s.modify_record(t,ph_num); cout<<”成功修改“< } cout<<”是否继续?(Y or N)“< cin>>w; } while(w=='Y'); break;} case 3: { system(”cls“); cout<<”********************************************“< 删除记录 “< cout<<”************** ***************************“< char w; char na[M]; int k; Fphone *p; do { cout<<”请输入您要删除的用户的姓名“; cin>>na; p=s.query(na); if(p==0) cout<<”没有该用户!“< else {(*p).disp(); k=p-s.getuser(); s.delete_record(p,k); } cout<<”是否继续?(Y or N)“< cin>>w; } while(w=='Y'); break;} case 4: { system(”cls“); cout<<”*********************************“< cout<<” 查询记录 “< cout<<”**********************************“< char na[M];int p=1; Fphone *t=NULL; char w; do { cout<<”请输入您要查询的用户的姓名“; cin>>na; t=s.query(na); if(t) { cout<<”姓名:“< cout<<”电话号码:“< } else cout<<”对不起,没有此人信息!“< cout<<”是否继续?(Y or N)“< cin>>w;} } case 5: { while(w=='Y');break;system(”cls“); cout<<” 请选择排序方式 “< cout<<” 1.按姓名(升序) “< cout<<” 2.按电话号码(升序) “< cout<<” 3.按姓名(降序) “< cout<<” 4.按电话号码(降序) “< cout<<” 请输入你的选择: “< int k; cin>>k; switch(k) { case 1: s.sorta_name(); cout<<”排序完成“< system(”cls“); break; case 2: s.sorta_phonenum(); cout<<”排序完成“< system(”cls“); break; case 3: s.sort_name(); cout<<”排序完成“< system(”cls“); break; case 4: s.sort_phonenum(); cout<<”排序完成“< system(”cls“); break; } } case 6: { system(”cls“); cout<<”*****************************************“< cout<<” 显示记录 “< cout<<”*****************************************“< s.disp(); system(”pause“);break; } } } case 7: { system(”cls“); cout<<”您确定要删除所有记录吗?(Y or N)“< char q; cin>>q; if(q=='Y'||q=='y') { cout<<”*********************************“< cout<<” 全部删除记录 “< cout<<”*********************************“< s.clear(); } else break; system(”pause“); break;} case 0: { system(”cls“); cout<<”谢谢使用,再见!“< exit(0);} default: cout<<”不存在该选择,请重新输入要进行的操作:“< system(”pause"); break;} 七.感想与心得 1.电话簿管理程序较长,算法比较复杂,调试的过程中遇到了各种各样的问题。各种各样的小错误寻找起来十分困难。在今后编写程序时应当随编随找错。 2.课设让我们把这一学期所学的C++知识得到了很好的应用,开拓了我们的思路,所谓温故而而知新,这次课设也让我们对以前的知识有了一个全面的回顾,加深了对已学知识的理解。 3.课设过程艰辛,花费时间很长,需要很强的耐力和信心。而这也是对我们的一次考验,养成了坚持不懈和吃苦耐劳的精神。总之,C++课设让我们学到了很多,也收获了很多,这必将成为我人生中的一个深刻的回忆。 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++课程设计 题目名称 图书管理系统 2016 年月 29 日 目录 一.设计内容与要求...............................................................................................................2 二.设计思路:.......................................................................................................................4 三.关键模块实现及主要代码...............................................................................................4 四.实验结果及分析.............................................................................................................13 五、心得体会.........................................................................................................................16 六、参考文献.........................................................................................................................17 一.设计内容与要求 (1)、设计一个图书管理系统,能够实现用户信息管理,图书信息的 录入、查询、删除等功能。 (2)、实现用户管理,系统具有用户注册功能。管理员的账号和密码由系统指定,登录后可进行修改。一般用户注册后才能登录使用系统。管理员具有录入、查询、删除图书信息及一般用户的功能。一般用户只有图书查询功能。 (3)、登录功能,只有注册了的用户才能进入系统,没有注册的则有提示信息出现。 (4)、图书管理功能,管理员能够录入、查询、删除图书信息。(5)、图书查询功能,管理员及一般用户能够通过图书的基本信息,如图书作者、书名、出版社、出版日期等等,进行查询。 提示:上述为基本功能,可参考实际的系统进行扩展。 二.设计思路: 为了实现用户信息以及图书信息的管理,建立一个用户CUser类与图书信息CBoodata类,其中CUser类应该包含用户账号以及密码,CBookdata类应该包含图书作者,书名,出版社,出版日期。同时应该建立两个dat文件,一个为存储用户信息,一个用来储存图书信息。程序主要分为4个页面:(1)登录页面,由Cdialog类派生出CMyprojectDlg类,用来处理账号注册与用户登录。 (2)图书查询页面。由Cdialog类派生出CSearch类。包含读取所有图书数据响应函数,以及根据作者姓名或者书名来查询图书响应函数。 (3)管理员图书管理页面。由Cdialog类派生出CBookdata类。包含读取所有图书响应函数,添加图书响应函数,修改图书响应函数,删除图书响应函数。(4)用户信息管理页面,由Cdialog类派生出CUserdata类。包含读取所有用户信息响应函数,删除用户响应函数、添加用户响应函数、修改用户信息响应函数。 因为本人能力有限,而且自己是根据老师给的教程以及结合书本内容来完成课程设计,于是我第一想到的就是应数组来存储信息,而不是用链表,所以,对于文件数据的删除与修改,难免会过于乏力。 三.关键模块实现及主要代码 (1)自己建立的类 1.用户类: class CUser { public: int num;char password[20];}; 2.图书信息类: class Book //图书类 { public: char author[10]; //设置作者姓名 char bname[20]; //设置图书书名 char pub_name[20]; //设置出版社名称 int pub_date; //设置出版年月 }; (2)登录页面,由Cdialog类派生出CMyprojectDlg类,用来处理账号注册与用户登录。1.用户注册处理响应函数: void CMyprojectDlg::OnButton3() //用户注册 { // TODO: Add your control notification handler code here ////////////////////////////////////////////////////////////////////////////////////// //以下代码主要还是把这条记录写入文件,注意写入的格式:文件的前四个字节是保持用户记录数,//后面依次保持用户记录注意,写用户的每个信息的顺序要与读取时的顺序一致。 UpdateData(TRUE);CUser user;int n_user=0; //用户的个数,管理员默认为第一个。自己输入为账号:1111,密码:0000。 int size=0; fstream file(“user.dat”,ios::in|ios::out);// 建立一个文件类,关于其用法,请baidu。 file.seekg(ios::beg); //将文件指针指向文件头。 file.read((char*)&n_user,sizeof(n_user)); //读取用户数。 n_user+=1;file.seekp(ios::beg);file.write((char*)&n_user,sizeof(n_user));//写学生记录个数 user.num=m_num; //之前定义user.password为string,导致密码匹配时有错误。。。 memcpy(user.password,m_password.GetBuffer(m_password.GetLength()),m_password.GetLength());// 把类CString对象的内容赋值到字符数组中 user.password[m_password.GetLength()]=' ';//在数组末尾加结束符号 //在文件末尾,把新的记录写入。 file.seekp(4+(n_user-1)*sizeof(CUser),ios::beg); //这里出错 file.write((char*)&user.num,sizeof(user.num));file.write((char*)&user.password,sizeof(user.password)); file.close(); ///////////////////////////////////////////////////////////////////////////////////////// //用消息框提示 CString str;str.Format(“成功注册,成为第 %d 个注册用户,请按确定返回重新登录.”,n_user-1); ///因为第一个为管理员,不算为用户人数。 AfxMessageBox(str); } 2.用户登录处理响应函数。其中包含判断是管理员,还是普通用户。void CMyprojectDlg::OnButton2() //用户登录 { // TODO: Add your control notification handler code here UpdateData(TRUE); CUser m_user[100];int i;int size;int n_user=0;//文件中用户的个数 ////////////////////////////////////////////////////////////////////////////////////////// //读取文件中的用户记录,注意读取顺序与写入的顺序要一致,文件最开始的4个字节是表示记录个数。 //根据记录个数,依次读取用户记录 放在成员变量m_st数组中(已在类体中声明了) CFile file; file.Open(“user.dat”,CFile::modeReadWrite);size=GetFileSize((void*)file.m_hFile,NULL);//读取文件大小,size==0表示是空文件 if(size>0){ file.SeekToBegin(); file.Read(&n_user,sizeof(n_user));} if(n_user>0 && n_user<99)//实验中限定为0~100个用户记录 { for(i=0;i { //请注意与写入数据的顺序要保持一样,否则会读错数据。 file.Read(&(m_user[i].num),sizeof(m_user[i].num)); file.Read(&(m_user[i].password),sizeof(m_user[i].password)); } } file.Close();///////////////////////////////////////////////// if(m_num==1111&&m_password==“0000”) //管理员进入管理员页面 { CAdministrators administrators; administrators.DoModal();} CString str_password;for(i=0;i //普通用户,进入图书查询页面 { str_password=m_user[i].password; if(m_user[i].num==m_num) { if(str_password==m_password) { CSearch search; search.DoModal(); } else { CString str; str.Format(“密码或者账号错误,请重新输入!”); AfxMessageBox(str); } } } } (3)图书查询页面。包含读取所有图书数据,以及根据作者姓名或者书名来查询图书。1.读取所有图书响应函数。 void CSearch::OnButton5() //显示出所有图书 { // TODO: Add your control notification handler code here int i;int size;int n_book=0;//文件book的本数 ////////////////////////////////////////////////////////////////////////////////////////// //读取文件中的书本记录,注意读取顺序与写入的顺序要一致,文件最开始的4个字节是表示记录个数。 //根据记录个数,依次读取书籍记录 放在成员变量m_user_book数组中(已在类体中声明了) CFile file; file.Open(“book.dat”,CFile::modeReadWrite);size=GetFileSize((void*)file.m_hFile,NULL);//读取文件大小,size==0表示是空文件 if(size>0){ file.SeekToBegin(); file.Read(&n_book,sizeof(n_book));} if(n_book>0 && n_book<99)//实验中限定为0~100个书本记录 { m_num_book=n_book; for(i=0;i { //请注意与写入数据的顺序要保持一样,否则会读错数据。 file.Read(&(m_user_book[i].author),sizeof(m_user_book[i].author)); file.Read(&(m_user_book[i].bname),sizeof(m_user_book[i].bname)); file.Read(&(m_user_book[i].pub_name),sizeof(m_user_book[i].pub_name)); file.Read(&(m_user_book[i].pub_date),sizeof(m_user_book[i].pub_date)); } } file.Close();///////////////////////////////////////////////// //在列表控件中显示所有条记录 //插入每列的表头; m_list.InsertColumn(0,“作者”,LVCFMT_LEFT,100,1); m_list.InsertColumn(1,“书名”,LVCFMT_LEFT,100,1);m_list.InsertColumn(2,“出版社”,LVCFMT_LEFT,100,1);m_list.InsertColumn(3,“出版日期”,LVCFMT_LEFT,100,1);//每一行插入一条书本记录 for(i=0;i CString str; str=m_user_book[i].author; m_list.InsertItem(i,str);//InsertItem向CListCtr控件申请一行用来存放数据,同时写入一行的头名称(即编号为0列的数据) str=m_user_book[i].bname; m_list.SetItemText(i,1,str);//设置第i行第1列的的数据为书名 str=m_user_book[i].pub_name; m_list.SetItemText(i,2,str);//设置第i行第2列的的数据为出版社 str.Format(“%d”,m_user_book[i].pub_date); ///整型变为字符串,便于在控件显示 m_list.SetItemText(i,3,str);//设置第i行第3列的的数据为出版日期 } } 2.图书查询响应函数。 void CSearch::OnButton4() //查询图书 { // TODO: Add your control notification handler code here UpdateData(TRUE);m_list.DeleteAllItems();int num=0;//表示查找结果的个数 int i; for(i=0;i { CString str; int ret1=0,ret2=0; str=m_user_book[i].author; ret1=str.Find(m_author,0);//ret1>=0, 表示str中包含了m_author的字段 str=m_user_book[i].bname; ret2=str.Find(m_bname,0);//ret2>=0, 表示str中包含了m_bname的字段 if(ret1>=0) //按作者查询 { str=m_user_book[i].author; m_list.InsertItem(num,str);//InsertItem向CListCtr控件申请一行用来存放数据,同时写入一行的头名称(即编号为0列的数据) str=m_user_book[i].bname; m_list.SetItemText(num,1,str);//设置第i行第1列的的数据为书名 str=m_user_book[i].pub_name; m_list.SetItemText(num,2,str);//设置第i行第2列的的数据为出版社 str.Format(“%d”,m_user_book[i].pub_date); ///整型变为字符串,便于在控件显示 m_list.SetItemText(num,3,str);//设置第i行第3列的的数据为出版日期 num+=1;//结果+1; } } } (4)管理员图书管理页面。包含读取所有图书,添加图书,修改图书,删除图书的功能。1.读取所有图书功能实现与(3)的实现一样。2.添加图书响应函数。 void CBookdata::OnButton7() //添加图书 { UpdateData(TRUE);Book book;int n_book=0; //书本的个数 int size=0; fstream file(“book.dat”,ios::in|ios::out);// 建立一个文件类,关于其用法,请baidu。 file.seekg(ios::beg); //将文件指针指向文件头。 file.read((char*)&n_book,sizeof(n_book)); //读取书籍数。 ////////////////////////////////////////////////////////////////////////////////////// //以下代码主要还是把这条记录写入文件,注意写入的格式:文件的前四个字节是保持书本记录数,//后面依次保持书本记录注意,写学生的每个信息的顺序要与读取时的顺序一致。 n_book+=1;file.seekp(ios::beg);file.write((char*)&n_book,sizeof(n_book));//写学生记录个数 memcpy(book.author,m_add_author.GetBuffer(m_add_author.GetLength()),m_add_author.GetLength());// 把类CString对象的内容赋值到字符数组中 book.author[m_add_author.GetLength()]=' ';//在数组末尾加结束符号 memcpy(book.bname,m_add_bname.GetBuffer(m_add_bname.GetLength()),m_add_bname.GetLength());// 把类CString对象的内容赋值到字符数组中 book.bname[m_add_bname.GetLength()]=' ';//在数组末尾加结束符号 memcpy(book.pub_name,m_add_pub_name.GetBuffer(m_add_pub_name.GetLength()),m_add_pub_name.GetLength());// 把类CString对象的内容赋值到字符数组中 book.pub_name[m_add_pub_name.GetLength()]=' ';//在数组末尾加结束符号 book.pub_date=m_add_pub_date; //在文件末尾,把新的记录写入。 file.seekp(4+(n_book-1)*54,ios::beg); file.write((char*)&book.author,sizeof(book.author));file.write((char*)&book.bname,sizeof(book.bname));file.write((char*)&book.pub_name,sizeof(book.pub_name));file.write((char*)&book.pub_date,sizeof(book.pub_date)); file.close();///////////////////////////////////////////////////////////////////////////////////////// //用消息框提示 CString str;str.Format(“文件中已有 %d 本书籍记录.”,n_book);AfxMessageBox(str);} 3.修改图书响应函数。 void CBookdata::OnButton5() //修改图书,,必须先读取图书才能修改图书。{ // TODO: Add your control notification handler code here UpdateData(TRUE);m_list.DeleteAllItems();m_list.InsertColumn(0,“作者”,LVCFMT_LEFT,100,1); m_list.InsertColumn(1,“书名”,LVCFMT_LEFT,100,1);m_list.InsertColumn(2,“出版社”,LVCFMT_LEFT,100,1);m_list.InsertColumn(3,“出版日期”,LVCFMT_LEFT,100,1); CString str_author,str_bname,str_pub_name,str; //将book类的字符串数组赋值为字符串变量,方便比较。 CFile file;// 建立一个文件类,关于其用法,请baidu。 file.Open(“book.dat”,CFile::modeReadWrite);//打开文件 file.SeekToBegin(); file.Write(&m_num_book,sizeof(m_num_book));//写书本记录本数 for(int i=0;i { str_author=m_book[i].author; str_bname=m_book[i].bname; str_pub_name=m_book[i].pub_name; if(str_author==m_author||str_bname==m_bname||str_pub_name==m_pub_name||m_book[i].pub_date==m_pub_date) { memcpy(m_book[i].author,m_modify_author.GetBuffer(m_modify_author.GetLength()),m_modify_author.GetLength());// 把类CString对象的内容赋值到字符数组中 m_book[i].author[m_modify_author.GetLength()]=' ';//在数组末尾加结束符号 memcpy(m_book[i].bname,m_modify_bname.GetBuffer(m_modify_bname.GetLength()),m_modify_bname.GetLength());// 把类CString对象的内容赋值到字符数组中 m_book[i].bname[m_modify_bname.GetLength()]=' ';//在数组末尾加结束符号 memcpy(m_book[i].pub_name,m_modify_pub_name.GetBuffer(m_modify_pub_name.GetLength()),m_modify_pub_name.GetLength());// 把类CString对象的内容赋值到字符数组中 m_book[i].pub_name[m_modify_pub_name.GetLength()]=' ';//在数组末尾加结束符号 m_book[i].pub_date=m_modify_pub_date; } ////////////////////////////////////////////////////////////////////////////////////// //以下代码主要还是把这条记录写入文件,注意写入的格式:文件的前四个字节是保持学生记录数,//后面依次保持学生记录注意,写学生的每个信息的顺序要与读取时的顺序一致。 file.Write(&m_book[i].author,sizeof(m_book[i].author)); file.Write(&m_book[i].bname,sizeof(m_book[i].bname)); file.Write(&m_book[i].pub_name,sizeof(m_book[i].pub_name)); file.Write(&m_book[i].pub_date,sizeof(m_book[i].pub_date)); ///////////////////////////////////////////////////////////////////////////////////////// //在列表控件中显示所有条记录 str=m_book[i].author; m_list.InsertItem(i,str);//InsertItem向CListCtr控件申请一行用来存放数据,同时写入一行的头名称(即编号为0列的数据) str=m_book[i].bname; m_list.SetItemText(i,1,str);//设置第i行第1列的的数据为书名 str=m_book[i].pub_name; m_list.SetItemText(i,2,str);//设置第i行第2列的的数据为出版社 str.Format(“%d”,m_book[i].pub_date); ///整型变为字符串,便于在控件显示 m_list.SetItemText(i,3,str);//设置第i行第3列的的数据为出版日期 } file.Close(); //用消息框提示 str.Format(“成功修改书籍记录.”);AfxMessageBox(str);} 4.删除图书响应函数。 void CBookdata::OnButton6() //删除图书,,读取了图书数据后才能删除图书 { // TODO: Add your control notification handler code here UpdateData(TRUE);m_list.DeleteAllItems();m_list.InsertColumn(0,“作者”,LVCFMT_LEFT,100,1); m_list.InsertColumn(1,“书名”,LVCFMT_LEFT,100,1);m_list.InsertColumn(2,“出版社”,LVCFMT_LEFT,100,1);m_list.InsertColumn(3,“出版日期”,LVCFMT_LEFT,100,1); CString str_author,str_bname,str_pub_name,str; //将book类的字符串数组赋值为字符串变量,方便比较。 int n_book,n_flag=0; // n_flag为删除标志,1为有元素删除了 CFile file;// 建立一个文件类,关于其用法,请baidu。 file.Open(“book.dat”,CFile::modeReadWrite);//新建一个文件并且打开文件 file.SeekToBegin(); file.Write(&m_num_book,sizeof(m_num_book));//写书本记录本数,先填入本来的书本数。 for(int i=0;i { str_author=m_book[i].author; str_bname=m_book[i].bname; str_pub_name=m_book[i].pub_name; if(str_author==m_del_author||str_bname==m_del_bname||str_pub_name==m_del_pub_name||m_book[i].pub_date==m_del_pub_date) { n_flag=1; //删除标志置1 i+=1; //第i个元素为要删除元素,跳过 } ////////////////////////////////////////////////////////////////////////////////////// //以下代码主要还是把这条记录写入文件,注意写入的格式:文件的前四个字节是保持 学生记录数,//后面依次保持学生记录注意,写学生的每个信息的顺序要与读取时的顺序一致。 file.Write(&m_book[i].author,sizeof(m_book[i].author)); file.Write(&m_book[i].bname,sizeof(m_book[i].bname)); file.Write(&m_book[i].pub_name,sizeof(m_book[i].pub_name)); file.Write(&m_book[i].pub_date,sizeof(m_book[i].pub_date)); } if(n_flag==1) { n_book=m_num_book-1; //表示删除了一本书,则将文件的书本数减1。 file.SeekToBegin(); file.Write(&n_book,sizeof(n_book));//写书本记录本数,先填入本来的书本数。 //用消息框提示 str.Format(“成功删除书籍记录.”); AfxMessageBox(str); } else { //用消息框提示 str.Format(“没有这一本书的记录,不能删除.”); AfxMessageBox(str); } file.Close();} (5)、用户信息管理页面,包含读取所有用户信息,删除、添加、修改用户信息。1.读取所有用户信息以(4)基本相同。 2.删除用户信息实现基本方法与(4)基本相同。3.添加用户信息实现基本方法与(4)基本相同。4.修改用户信息实现基本方法与(4)基本相同。 四.实验结果及分析 (1.)登录页面 成功注册 普通用户成功登录页面 查询结果 管理员登录页面 图书管理页面 成功添加图书。 用户信息管理页面 分析:基本功能是可以实现的,但是因为是用数组来存放图书信息与用户信息,所以对于数据大了之后处理能力不够方便以及效率不高。而且删除信息的时候只是删除该条数据的信息,数据后面的信息往上移动,所以最后面会有两条重复的信息,虽然文件开头储存信息数目已经减一,读取数据是按照文件开头储存的信息数目来读取信息,但是有时候读取会有乱码。我在程序中找不到那个隐藏的bug,五、心得体会 这次C++课程设计学到了很多,懂得了C++看起来虽然简单,可是要用这个计算机语言来实现一些有用的功能,怎么运用确实是一门挺高深的学问,我们学习计算机语言不能只是看书看概念,要多上机实验,这样才能对计算机语言有比较深的了解,才能够提高自己的编程以及调试找BUG的能力。现在来总结一下编程过程中遇到的一些值得注意的问题。 1.派生出一个类时,为编辑框增加变量名后,然后在类声明中自己增加类成员,如果再想在对话框中增加编辑框并且添上变量名会出现错误。(如下,在Csearch 类中自己添加下面箭头指向的代码后,会出现下图右的错误,解决方法是把箭头指向的代码放到//}}AFX_DATA后面,因为此语句为MFC对话框自行添加编辑变量的结束,如果我们将自己定义的变量也添加到此语句前,编译器不清楚是MFC自行添加的变量还是用户自行添加的变量。)2.遇到编译器没有出错,可是运行结果与自己想象的不一样,很可能是逻辑错误。如: 在用户注册时,我是将用户数据直接存到文件尾,这是不正确的,因为管理员页面有删除用户的功能,这个功能的原理是先读文件头的用户数(假定为10个),然后将用户的数据先读取出来,然后经过一个判断,再储存重新储存回文件,而文件中储存的用户数据大小是没有变化的,也就是说文件尾会有两份最后一个用户的数据(即如果删除的是第七个,文件中最后会有两份第十个用户的数据,文件头的记录用户数为9个),如果添加用户直接储存在文件尾则会储存在第11个用户的位置,可是以后读取的话只是读取到第10个。所以会出现读取错误,密码不匹配的问题。应该根据记录的用户数让文件指针指向最后一个用户数据后面。file.seekp(4+(n_user-1)*sizeof(CUser),ios::beg); 以上两个问题是困扰我比较久的,其他问题经过百度还有自己的调试,解决还算快,不值得重点说。 六、参考文献 1.C++面向对象程序设计(第二版) 谭浩强 编著 2.成绩管理系统MFC教程 3.CNDN论坛,关于文件操作的指针运算。 #include void menu(University uni);//菜单函数声明 class Student//学生类 { public: string name;int age;string sex;int number;string major; public: void disp_stu(); friend void file_in(University &uni); friend void file_out(University uni);};void Student::disp_stu(){ } class Institute//学院类 { public: string name;cout<<“学生姓名:”< public: void add_stu(); //添加学生 bool delete_stu(int i); // 删除学生 bool modefy_stu(int i); //修改学生信息 void disp_ins_1(); // 显示本院学生信息 friend void file_in(University &uni); friend void file_out(University uni);};void Institute::add_stu(){ } Student *p=new Student;cout<<“学生名字:”;cin>>(*p).name;cout<<“学生年龄:”;cin>>(*p).age;cout<<“学生性别:”;cin>>(*p).sex;cout<<“学生学号:”;cin>>(*p).number;cout<<“学生专业:”;cin>>(*p).major;head.Add(p);//在链表末尾增加一个节点 bool Institute::delete_stu(int i){ } head.Remove(i);//删除链表指定位置节点 return true;bool Institute::modefy_stu(int i){ Student *p=new Student;cout<<“学生名字:”;cin>>(*p).name;cout<<“学生年龄:”;cin>>(*p).age;cout<<“学生性别:”;cin>>(*p).sex;cout<<“学生学号:”;cin>>(*p).number;cout<<“学生专业:”;cin>>(*p).major;head.Remove(i);//删除链表指定位置节点 head.Insert(i,p);//在链表指定位置插入一个新节点 return true;} void Institute::disp_ins_1(){ } class University//学校类 { public: string name;int age;string addr;List void design_stu();//学生信息设置 int i;Node cout<<“学院名字:”< } cout<<“-------”<pData->disp_stu();q=q->pNext; void add_ins(); //添加学院 bool delete_ins(int n); // 删除学院 void design_cqut(); //设置学校信息 bool modefy_cqut(); //修改学校信息 void disp_cqut(); //显示学校信息 void design_ins(); //学院信息设置 bool modefy_ins(int n); //修改学院 void disp_ins(); //显示学院信息 void search_menu();void search_name(string n);//姓名 void search(string n);//性别//函数重载 void search(int n);//学号 bool search_age(int n);//年龄 friend void file_in(University &uni);};friend void file_out(University uni); void University::design_stu(){ int i,m,j;int n;cout<<“ ★★★★★★学生信息设置★★★★★★ ”< { disp_ins(); cout< cout<<“输入学生所在学院序号:”< cin>>m;system(“cls”);//清屏 head.pCurrent=head.pHead;//当前指针指向双向链表头指针 for(j=1;j { } } head.pCurrent=head.pCurrent->pNext;//当前指针指后移 cout<<“输入要添加的学生信息:”;head.pCurrent->pData->add_stu();cout<<“按任意键返回上一级菜单:”< disp_ins(); cout< cout<<“输入学生所在学院序号:”< cin>>m;system(“cls”);//清屏 head.pCurrent=head.pHead;//当前指针指向双向链表头指针 for(j=1;j { head.pCurrent=head.pCurrent->pNext;//当前指针指后移 } } head.pCurrent->pData->disp_ins_1();cout< { disp_ins(); cout< cout<<“输入学生所在学院序号:”< cin>>m;system(“cls”);//清屏 head.pCurrent=head.pHead;//当前指针指向双向链表头指针 for(j=1;j { } } head.pCurrent=head.pCurrent->pNext;//当前指针指后移 head.pCurrent->pData->disp_ins_1();cout< } cin>>n;head.pCurrent->pData->modefy_stu(n);cout<<“按任意键返回上一级菜单:”< void University::add_ins(){ } bool University::delete_ins(int n){ } bool University::modefy_ins(int n){ Institute *p=new Institute;cout<<“学院名字:”;cin>>(*p).name;head.Remove(n);//删除链表指定位置节点 head.Insert(n,p);//在指定位置插入节点信息 return true;head.Remove(n);//删除链表指定位置节点 return true;Institute *p=new Institute;cout<<“学院名字:”;cin>>(*p).name;head.Add(p);//在链表末尾增加一个节点 } void University::disp_ins(){ int i;Node for(i=1;i<=head.size;i++){ cout<pData->name< } void University::design_ins(){ int i;int j;cout<<“ ★★★★★★学院信息设置★★★★★★ ”< cout< { } disp_ins();cout<<“按任意键返回上一级菜单:”< disp_ins(); add_ins(); cout<<“按任意键返回上一级菜单:”< getch();system(“cls”);//清屏 design_ins(); break;} case 3: { } disp_ins();cout<<“输入删除学院序号:”;cin>>j;delete_ins(j);cout<<“按任意键返回上一级菜单:”< disp_ins();cout<<“输入修改学院序号:”;cin>>j;modefy_ins(j);cout<<“按任意键返回上一级菜单:”< } case 5:menu(*this);break;} } bool University::modefy_cqut(){ cout<<“学校名字:”;cin>>name;cout<<“创建年代:”;cin>>age;cout<<“学校地址:”;cin>>addr;return true;} void University::design_cqut(){ int i; University uni;cout<<“ ★★★★★★学校信息设置★★★★★★ cout< switch(i){ case 1: { disp_cqut(); cout<<”按任意键返回上一级菜单:“< getch();system(”cls“);//清屏 design_cqut(); break; } case 2: { modefy_cqut(); cout<<”按任意键返回上一级菜单:“< getch();system(”cls“);//清屏 design_cqut();break;”< } } } case 3:menu(uni);break; void University::disp_cqut(){ cout<<“学校有关信息为:”< } void University::search_name(string n){ int i,j,m=0;head.pCurrent=head.pHead;//当前指针指向学院节点头指针 for(i=0;i for(j=0;j { if(n==head.pCurrent->pData->head.pCurrent->pData->name) { } head.pCurrent->pData->head.pCurrent->pData->disp_stu();m++;head.pCurrent->pData->head.pCurrent=head.pCurrent->pData->head.pCurrent->pNext;//学生当前指针后移 } bool University::search_age(int n){ int i,j,m=0;head.pCurrent=head.pHead;for(i=0;i } cout<<“有”< } head.pCurrent->pData->head.pCurrent=head.pCurrent->pData->head.pHead;for(j=0;j } head.pCurrent->pData->head.pCurrent->pData->disp_stu();m++;head.pCurrent->pData->head.pCurrent=head.pCurrent->pData->head.pCurrent->pNext;} head.pCurrent=head.pCurrent->pNext;} cout<<“有”< void University::search(string n){ } int i,j,m=0;head.pCurrent=head.pHead;for(i=0;i for(j=0;j if(n==head.pCurrent->pData->head.pCurrent->pData->sex){ head.pCurrent->pData->head.pCurrent->pData->disp_stu();} m++; head.pCurrent->pData->head.pCurrent=head.pCurrent->pData->head.pCurrent->pNext; } cout<<“有”< int i,j,m=0;head.pCurrent=head.pHead;for(i=0;i head.pCurrent->pData->head.pCurrent=head.pCurrent->pData->head.pHead; for(j=0;j { if(n==head.pCurrent->pData->head.pCurrent->pData->number) { head.pCurrent->pData->head.pCurrent->pData->disp_stu(); m++; } head.pCurrent->pData->head.pCurrent=head.pCurrent->pData->head.pCurrent->pNext; } head.pCurrent=head.pCurrent->pNext;} cout<<“有”< /****************************************信息查询菜***********************************************/ void University::search_menu(){ int i;cout<<“ ★★★★★信息查询显示★★★★★”< switch(i){ case 1: { 单 disp_ins(); cout<<“按任意键返回上一级菜单:”< { } head.pCurrent=head.pHead;//当前指针指向学院节点头指针 for(i=0;i } head.pCurrent->pData->disp_ins_1();head.pCurrent=head.pCurrent->pNext;cout<<“按任意键返回上一级菜单:”< } int j;disp_ins();cout<<“请输入学生所在学院序号:”;cin>>i;system(“cls”);//清屏 head.pCurrent=head.pHead;for(j=1;jpNext;head.pCurrent->pData->disp_ins_1();cout<<“按任意键返回上一级菜单:”< case 4: { string n;cout<<“输入要查询的姓名:”;cin>>n;system(“cls”);//清屏 search_name(n); } cout<<“按任意键返回上一级菜单:”< { } int n1;cout<<“输入要查询的年龄:”;cin>>n1;search_age(n1);cout<<“按任意键返回上一级菜单:”< system(“cls”);//清屏 case 6: { } string n;cout<<“输入要查询的性别:”;cin>>n;system(“cls”);//清屏 search(n);cout<<“按任意键返回上一级菜单:”< } int n;cout<<“输入要查询的学号:”;cin>>n;system(“cls”);//清屏 search(n);cout<<“按任意键返回上一级菜单:”< menu(*this); } } } break;/**********************************************************************/ { int i,j;ifstream inf(“cqutData.txt”,ios::in);inf>>uni.name;inf>>uni.age;inf>>uni.addr;inf>>uni.head.size;//学院个数 for(i=0;i 导出文件数据void file_in(University &uni) Node else uni.head.pEnd->pNext=m;//把节点m赋给下一个学院信息节点 m->pPrev=uni.head.pEnd;//节点m指向学院信息的尾节点 uni.head.pCurrent=uni.head.pEnd=m;//学院信息的尾节点始终指向m节点 inf>>uni.head.pCurrent->pData->head.size;//学生个数 for(j=0;j Student *q=new Student;inf>>q->name;inf>>q->age;inf>>q->sex;inf>>q->number;inf>>q->major; Node n->pPrev=uni.head.pCurrent->pData->head.pEnd; uni.head.pCurrent->pData->head.pCurrent=uni.head.pCurrent->pData->head.pEnd=n;//学生信息的尾节点始终指向n节点 } } } /************************************************************************************/ void file_out(University uni){ ofstream ouf(“cqutData.txt”,ios::out);int i,j;ouf< 导入文件数据ouf< uni.head.pCurrent=uni.head.pHead;//当前指针指向学院节点头指针 for(i=0;i ouf< ouf< uni.head.pCurrent->pData->head.pCurrent=uni.head.pCurrent->pData->head.pHead;//当前指针指向学生节点头指针 for(j=0;j ouf< uni.head.pCurrent->pData->head.pCurrent=uni.head.pCurrent->pData->head.pCurrent->pNext;//学生当前指针后移 } } } uni.head.pCurrent=uni.head.pCurrent->pNext;//学院当前指针后移 /************************退出系统菜单****************************/ void exit(University uni){ } int i;cout<<“是否保存修改内容:”< { } file_out(uni);exit(0);break;case 2:{exit(0);break;} case 3: { menu(uni);break;} case 4: { file_out(uni); } } menu(uni);break; /***************************************************************************************/ void menu(University uni){ system(“cls”);/*清屏*/ int i;cout< 主菜单 cout<<“★★★★★★★★★★★★★主菜单★★★★★★★★★★★★★”< cout< cout< cout< } int main(){ University u; } file_in(u);menu(u);return 0;switch(i){ case 1:uni.design_cqut();break;case 2:uni.design_ins();break;case 3:uni.design_stu();break; case 4:uni.search_menu();break; case 5:exit(uni);break;} 课程设计总结 经过一个学期对《C++程序设计》的学习,我学习到了基本的理论知识,了解到了C++语言程序设计的思想,这些知识都为我的课程实践和进一步的学习打下了坚实的基础。在为期近两周的C++课程设计中,我体会颇多,学到了很多东西。我加强了对C++程序设计这门课程的认识,并且复习了自己以前学习到的知识。这些都使得我对计算机语言的学习有了更深入的认识!总之,通过这次课程设计,我收获颇丰,相信会为自己以后的学习和工作带来很大的好处。像职工信息表这样的程序设计,经历了平时在课堂和考试中不会出现的问题和考验。而这些问题,这并不是我们平时只靠课本,就可以轻易解决的。所以,锻炼了我们挑战难题,学会用已掌握的知识去解决具体问题的能力,进一步培养了独立思考问题和解决问题的能力。特别是学会了在Visual C++中如何调试程序的方法。当然,老师的指导和同学的帮助也是不可忽视的,他们给了我许多提示和帮助,教会了我编译复杂程序的方法。 在老师和同学的帮助下,通过自己的努力,终于完成了这次职工信息表的简单课程设计。我经过这段时间的编程,对其中的艰辛,我是深有体会。从刚开始的选择程序、理解程序到后来的调试程序以及改进程序这个过程中,我遇到了各种各样的困难和挫折。但是我坚定信念,对自己充满了信心,想尽一切办法克服重重困难。 通过课程设计的训练,我进一步学习和掌握了对程序的设计和编写,从中体会到了面向对象程序设计的方便和巧妙。懂得了在进行编写一个程序之前,要有明确的目标和整体的设计思想。另外某些具体的细节内容也是相当的重要。这些宝贵的编程思想和从中摸索到的经验都是在编程的过程中获得的宝贵财富。这些经验对我以后的编程会有很大的帮助的,我要好好利用。 虽然这次课程设计是在参考程序的基础之上进行的,但是我觉得对自己是一个挑战和锻炼。我很欣慰自己能在程序中加入自己的想法和有关程序内容,也就是对它的程序改进了一番改进,并有创新。但是我感觉自己的创新还不够典型,总之还不是很满意。另外由于时间的紧迫和对知识的了解不够广泛,造成了系统中还存在许多不足,功能上还不够完善。以后我会继续努力,大胆创新,争取能编写出透射着自己思想的程序。这次课程设计让我充分认识到了自己的不足,认识到了动手能力的重要性。我会在以后的学习中更加努力锻炼自己,提高自己,让自己写出更好更完善的程序,为以后的编程打好基础! 总而言之,这次C++程序设计实践让我收获很大。 计算机科学与技术13-2班 2010年7月4日第二篇:C++程序设计—电话簿管理系统
第三篇:C++课程设计(简单图书管理系统)
第四篇:C++课程设计(教务管理系统)
第五篇:c++课程设计总结