C++课程设计学生通讯管理系统.docx

上传人:b****7 文档编号:23716254 上传时间:2023-05-20 格式:DOCX 页数:72 大小:388.57KB
下载 相关 举报
C++课程设计学生通讯管理系统.docx_第1页
第1页 / 共72页
C++课程设计学生通讯管理系统.docx_第2页
第2页 / 共72页
C++课程设计学生通讯管理系统.docx_第3页
第3页 / 共72页
C++课程设计学生通讯管理系统.docx_第4页
第4页 / 共72页
C++课程设计学生通讯管理系统.docx_第5页
第5页 / 共72页
点击查看更多>>
下载资源
资源描述

C++课程设计学生通讯管理系统.docx

《C++课程设计学生通讯管理系统.docx》由会员分享,可在线阅读,更多相关《C++课程设计学生通讯管理系统.docx(72页珍藏版)》请在冰豆网上搜索。

C++课程设计学生通讯管理系统.docx

C++课程设计学生通讯管理系统

课程设计报告

一课程设计目的及要求

学生通讯系统

学生通信录信息包括:

姓名、学号、年龄、性别、家庭住址、联系电话、寝室号等信息。

现要求编写程序来完成如下功能:

●学生通信录信息的输入

●学生的通信录信息删除和修改

●学生的通信录信息查询和统计功能

●学生的通信录信息输出显示。

二课程设计具体实现

1.总体设计

学生通讯管理系统

只修改学号

管理员登陆系统

普通用户登陆系统

删除信息

退出系统

密码校验

增加信息

查找信息

修改信息

修改密码

全部修改

只修改姓名

2.详细设计

在进行系统的各项功能介绍之前,有必要先说一下我所选的课程项设计的主要思路。

这个系统的核心部分就是结构体链表,它贯穿整个程序。

一切数据的增、删、查、改都要以它为支撑。

整个程序其实就是在操作一张很大的链表。

我在15周时就已经开始考虑课程设计题目,当时是想先做一个关于面向过程的课题,立马就考虑的先用结构体链表做为数据的容器。

而且已经做成型了。

后来老师您把题目给改了,要求都用面向对象做,我是考虑过用vector或者是list来做数据的容器的,但想想程序几经初成型,就不改变容器了,就直接把类的对象做为结构体的数据部分,程序当然也有较大改动,但基本框架是没有变的。

先来说链表的构造,在主菜单下选择功能之前,链表就已经认构造完毕,程序按行读取文本文件,每读一行,便对其进行分割。

分割出来的字符串为学生类对象对应的每一项信息。

在分割字符串时,我按字符‘@’进行分割(当然,在数据存储时也是按行存储,且每项信息以‘@’分开),其关键代码如下:

voidread_info(){//读取文件

head=NULL;

Students;//构造学生类对象

ifstreamin("student_info.txt");

stringread;

intno;

while(getline(in,read)){//按行读取

no=0;

inti;

while(read.find_first_of("@")!

=-1){

stringtemp;

i=read.find_first_of("@");

temp=read.substr(0,i);

if(no==0){

s.name=temp;//赋予姓名

}

if(no==1){

s.tel=temp;//赋予电话

}

if(no==2){

s.xuehao=temp;//赋予学号

}

if(no==3){

s.sex=temp;//赋予性别

}

if(no==4){

s.banji=temp;//赋予班级

}

no++;

read=read.substr(i+1);

}

s.dizhi=read;//赋予地址

if(s.name.size()>0&&s.xuehao.size()>0){//判断学号与姓名是否为空

insert_into_list(s);//插入链表

}

}

in.close();

}

voidinsert_into_list(Studentst){

structlist*curr,*ne;

curr=(structlist*)new(structlist);//申请空间

curr->student=st;

ne=head;

if(head==NULL){//如果头指针为空插入第一条数据

head=curr;

curr->next=NULL;

}

else

{while(ne->next!

=NULL)ne=ne->next;//遍历结构体,直到尾

ne->next=curr;

curr->next=NULL;

}

}

Txt文件才的储存形式如下:

 

所以,能正确的读取所有数据在于字符串的分割,当然用此种方法读到的数据全是字符串,只是本系统为学生通讯系统,并不需要其他类型的数据,如有必要,字符串也可以转化。

就这样,当文件按行读取完毕时,链表中的每个结构体都包含有一个不同的学生类对象,至此,链表已初始化完毕。

在程序接下来的运行过程中,对数据的操作就是直接操作链表的节点。

下面对系统功能进行介绍:

i.

登陆系统:

通过欢迎界面后,将进入登陆方式选择界面,如图:

ii.若选择以普通用户身份登录系统,会出现以下界面:

普通用户的功能包括:

1.增加数据;2.查询数据;3.浏览数据;4.数据统计

1)增加数据功能的界面如下:

 

用户根据系统提示,对单个学生信息进行逐项输入,按回车键结束输入。

除姓名与学号外,其他信息只要直接按回车键就可以跳过输入,系统将保存为空。

对信息的输入还要有一定的规范性,如学号与电话为纯数字;姓名长度最多只有四个字;性别若有,只能为男或女,系统会自动对输入的信息进行校验,包括规范性校验与数据是否重复校验。

若无法通过校验,数据不会保存。

其关键代码如下:

●规范性校验:

boolStudent:

:

check_tel_xuehao(){//学号与电话检查函数

if(xuehao.size()==0){//如果学号为空,返回false

returnfalse;

}

if(!

check_string(xuehao)||!

check_string(tel)){//如果学号中处在数字以外的字符,返回false

cout<<"学号或电话输入有误!

"<

returnfalse;

}

returntrue;

}

boolcheck_string(stringa){//检测字符串中是否只包含数字

charb;

for(inti=0;i

{

b=a.at(i);

if(b>'9'||b<'0')returnfalse;

}

returntrue;

}

boolStudent:

:

check_name_other(){//姓名检测函数

if(name.size()==0||name.size()>10){//如果姓名为空或者姓名长度过长

cout<<"姓名输入有误!

"<

returnfalse;

}

else

returntrue;

}

boolStudent:

:

check_sex(){//此为性别检测函数,性别可以为空,可以为男,也可以为女,但不可以为其他字符,或者返回false

if(sex.size()>2||(sex.size()>0&&(pare("男")&&pare("女")))){

cout<<"性别输入错误!

"<

returnfalse;

}

else

returntrue;

}

●数据是否重复校验代码如下:

structlist*User:

:

check_repeat(stringkey,inttype){//此函数也可用于数据查询,key代表要查询的关键字。

type=1表示按姓名查找,type=2表示按学号查找

structlist*ne;

ne=head;//注意这个head不能空,要初始化

intcom;

while(ne!

=NULL){//遍历列表

com=0;

if((type==1||type==0)&&!

pare(ne->student.name))com++;//对比姓名

if((type==2||type==0)&&!

pare(ne->student.xuehao))com++;//对比学号

if(com>0){//若m>0,证明原有数据中含有被检数据,或者的话,将会返回NULL。

returnne;

}

if(ne->next==NULL)break;

ne=ne->next;

}

cout<

returnNULL;

}

2)数据查询功能界面如下:

 

进行数据查询时,可输入任何字符,只要学生信息中任何一项包含输入的关键字,该信息都会被显示出来,如上图,分别输入了“女”,“B105”,进行查询,结果信息都完整的显示了出来,以下是进行信息查询的关键代码:

voidUser:

:

find_info(){

stringkey;//关键字

structlist*ne;//结构体指针

intfind;//找到的数据量

intcom;

chars;//选择

FIND:

system("cls");

cout<<"请输入要查询的关键字:

";

cin>>key;

ne=head;//注意这个head不能空,要初始化

find=0;

show_table_head();

while(ne!

=NULL){//遍历链表,指针每移一位都要调出指针所指的学生类,然后进行每项数据的对比

com=0;

if(check_string(ne->student.name,key))com++;//如果相关信息内包含关键字,com++,下同

if(check_string(ne->student.banji,key))com++;

if(check_string(ne->student.dizhi,key))com++;

if(check_string(ne->student.sex,key))com++;

if(check_string(ne->student.tel,key))com++;

if(check_string(ne->student.xuehao,key))com++;

if(com>0){//即至少有一项匹配,则横排显示

find++;

ne->student.show_info(find);

}

if(ne->next==NULL)break;//指针指向尾部,退出

ne=ne->next;

}

cout<<'\n'<<"找到"<

\n"<

cout<<"是否继续查找(y/n)?

";

cin>>s;

if(s=='y')gotoFIND;

}

3)数据浏览功能:

此功能可以显示所有存入的数据,界面如下:

在数据显示时,主要用的技术就是对结构体链表进行遍历,指针指向结构体的学生类对象,然后调用该类的自身数据显示函数,这样就可显示所有数据。

关键代码如下:

voidUser:

:

show_all(){//显示所有信息

system("cls");//清屏

structlist*ne;//链表指针

ne=head;//指向头指针

inti=1;

show_table_head();//显示表头

while(ne!

=NULL)//遍历链表

{

ne->student.show_info(i);//横排显示学生信息

i++;

if(ne->next==NULL)break;//如果到达尾指针,退出

ne=ne->next;//指针指向下一位

}

system("pause");

}

voidStudent:

:

show_info(inti){//横行显示信息

cout<

cout<

cout<

cout<

cout<

cout<

cout<

}

4)数据统计功能:

数据可以按照三种方式进行统计,即按性别、按班级,按住址。

计时,对应条目相等的数据会显示在同体列表下,并会显示数据总数。

一下截图是按住址统计的部分结果:

以下是关键代码:

voidUser:

:

tongji_info(){

TONGJI:

system("cls");

chars;

cout<<"选择您可以统计方式:

\n\t1.按性别统计\n\t2.按住址统计\n\t3.按班级统计\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n请选择:

";

cin>>s;

if(s=='1'){

find_info

(1);

}

elseif(s=='2'){

find_info

(2);

}

elseif(s=='3'){

find_info(3);

}

else{

err_show();

}

cout<<"\n继续还是回主菜单[1_or_2]:

";

cin>>s;

if(s=='1')gotoTONGJI;

}

voidUser:

:

find_info(inttype){

tyhead=NULL;

structlist*ne;//结构体list指针

ne=head;//注意这个head不能空,要初始化

while(ne!

=NULL){//遍历链表,指针每移一位都要调出指针所指的学生类,然后进行每项数据的对比

stringkey;

if(type==1){

key=ne->student.sex;

}

elseif(type==2){

key=ne->student.dizhi;

}

else{

key=ne->student.banji;

}

if(!

contain(key)){

add(key);

}

if(ne->next==NULL)break;//指针指向尾部,退出

ne=ne->next;

}

structtypelist*ne2;

ne2=tyhead;

system("cls");

while(ne2!

=NULL){//遍历链表typelist

show_table_head();//表头显示函数

stringkey;

key=ne2->atype;

if(key.size()==0){

key="其他";

cout<

"<

}

else

{

cout<

"<

}

if(ne2->next==NULL)break;//指针指向尾部,退出

ne2=ne2->next;

cout<

}

}

intsee_list(inttype,stringkey,boolnullinfo){//type条目类型,key表示此条目下的数据,此函数用于返回某项包含相同数据的数目

structlist*ne;//结构体list指针

ne=head;//注意这个head不能空,要初始化

intfind=0;

while(ne!

=NULL){//遍历链表,指针每移一位都要调出指针所指的学生类,然后进行每项数据的对比

inti=0;

if(type==1){

if(!

ne->pare(key)||((ne->student.sex.size())==0&&nullinfo))//检查性别是否匹配

{

find++;

ne->student.show_info(find);

}

}

elseif(type==2){

if(!

ne->pare(key)||((ne->student.dizhi.size()==0)&&nullinfo))//检查地址是否匹配

{

find++;

ne->student.show_info(find);

}

}

else{

if(!

ne->pare(key)||((ne->student.banji.size()==0)&&nullinfo))//检查班级是否匹配

{

find++;

ne->student.show_info(find);

}

}

if(ne->next==NULL)break;//指针指向尾部,退出

ne=ne->next;

}

returnfind;

}

voidadd(stringkey){

structtypelist*curr,*ne;//结构体typelist指针

curr=(structtypelist*)new(structtypelist);//申请空间

curr->atype=key;

ne=tyhead;//ne指向头指针,如果初始化数据时,文件中有数据,此时头指针一定不为空

if(tyhead==NULL){//若链表为空

tyhead=curr;//头指针指向current

curr->next=NULL;//current为第一数据,表头的next指针为空

}

else//如果头指针不为空

{

while(ne->next!

=NULL)//遍历链表,直到ne指针指向尾部

{

ne=ne->next;

}

ne->next=curr;//尾指针的next指针指向current,此时current已插入链表

curr->next=NULL;//current位于链表尾部,其next指针当为NULL

}

}

boolcontain(stringkey){

structtypelist*ne;//结构体指针typelist

ne=tyhead;

while(ne!

=NULL){//遍历链表

if(!

ne->pare(key))returntrue;

if(ne->next==NULL)break;//指针指向尾部,退出

ne=ne->next;

}

returnfalse;

}

iii.若选择以管理员身份登录系统

则会出现管理员界面:

 

当正确输入用户名与密码后,方可进行功能操作。

其中,增加数据、查询数据、浏览数据与数据统计功能与普通用户的代码实现相同,因为管理员类继承与普通用户类,所以此函数直接继承。

在此不多作描述。

下面介绍删除数据与修改数据功能。

1)数据修改

进行数据修改时,需要先输入正确的学号或姓名,在找到数据后,可按提示进行修改,次系统有一个方便的地放就是若不想修改某项数据,可直接按回车键,如下图。

关键代码实现如下:

voidManager:

:

edit_info(){

stringkey;//关键字

chars;

structlist*xiu;

EDIT:

system("cls");

Studenttemp;//用于做缓存的学生类对象

cout<<"\n请输入要修改的条目关键字:

";

cin.ignore(1024,'\n');

getline(cin,key);

if(((xiu=check_repeat(key,1))!

=NULL)||((xiu=check_repeat(key,2))!

=NULL)){

boolf;

xiu->student.show_info();//以下为数据录入

cout<<"\n请输入新数据,若不必修改,请直接按回车键:

\n";

cout<<"请输入姓名:

";

getline(cin,temp.name);

cout<<"请输入电话:

";

getline(cin,temp.tel);

cout<<"请输入学号:

";

getline(cin,temp.xuehao);

cout<<"请输入性别:

";

getline(cin,temp.sex);

cout<<"请输入班级:

";

getline(cin,temp.banji);

cout<<"请输入住址:

";

getline(cin,temp.dizhi);

//以下为数据检查

if(temp.name.size()>0){//若重输了姓名

if(check_repeat(temp.name,1)!

=NULL)gotoWRONG;//检查未通过

 

}elsetemp.name=xiu->student.name;

if(temp.xuehao.size()>0){

if(check_repeat(temp.xuehao,1)!

=NULL)gotoWRONG;

}elsetemp.xuehao=xiu->student.xuehao;

if(temp.sex.size()==0){

temp.sex=xiu->student.sex;

}

if(temp.tel.size()==0){

temp.tel=xiu->student.tel;

}

if(temp.banji.size()==0){

temp.banji=xiu->student.banji;

}

if(temp.dizhi.size()==0){

temp.dizhi=xiu->student.dizhi;

}

if(temp.check_name_other()&&(temp.check_sex()&&temp.check_tel_xuehao())){//数据规范性检查

xiu->student=temp;//对指针下数据进行修改

cout<<"\n修改成功!

"<

edit_flag=true;

cout<<"\n修改后的数据为:

"<

xiu->student.show_info();

gotoASK;

}

elsegotoWRONG;

}

else{

err_show();

cout<<"无效的数据,是否继续(y/n)?

"

cin>>s;

if(s=='y'){

gotoEDIT;

}

gotoASK;

}

WRONG:

err_show();

cout<<"\n错误!

未修改数据!

"<

ASK:

cout<<"\n继续还是回主菜单[1_or_2]:

";

cin>>s;

if(s=='1')gotoEDIT;

 

}

2)数据删除

删除数据需要先输入学号或姓名,数据的删除本质上就是链表节点的删除。

截图如下:

关键代码如下:

intManager:

:

del_info(){//删除信息

stringm;//删除的关键字

structlist*la,*ne;

chars;

DEL:

system("cls");

ne=head;

if(head==NULL){//如果数据为空

err_show();

cout<<"\n空链表!

不可进行下一步操作!

"<

gotoASK;

}

cout<<"输入要删除的学号或姓名:

";

cin.ignore(50,'\n');

getline(cin,m);

if(!

pare(head->student.name)||!

pare(head->student.xuehao)){//如果姓名或学号的所对对应的学生对象位于链表头部,则需要改变头指针,头指针指向内容将要删除

head=ne->next;//改变头指针

ne->student.show_info();//显示信息

cout<<"\n确认删除(y/n)?

";

c

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 法律文书 > 调解书

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1