C语言课程设计报告Word文件下载.docx
《C语言课程设计报告Word文件下载.docx》由会员分享,可在线阅读,更多相关《C语言课程设计报告Word文件下载.docx(76页珍藏版)》请在冰豆网上搜索。
4、进一步要求,修改记录设置密码操作。
要求:
1、用C语言实现程序设计;
2、利用结构体数组实现联系人信息的数据结构设计;
3、系统的各个功能模块要求用函数的形式实现;
4、界面友好(良好的人机交互),程序加必要的注释。
课程设计实验报告要求:
1、预习报告:
题目、课程设计任务、数据结构、程序的总体设计(算法)、模块划分。
2、实验总结报告:
流程图、主要源程序代码(需打印)、测试情况及调试中问题与解决方案、小结等。
一、总体设计
1.程序的总体设计
(1)函数名,变量名,名称常量的命名习惯:
在源代码中,自己写的函数的命名习惯为每个单词的首字母大写,如函数名“AddOneContacer”,“DeleteContacter”,以区别系统自定义和老师定义的函数;
而变量名采用小写,如果名字包括几个词,把他们连成一个,第一个词的字母小写,而后面的每个单词的首字母大写,如“contacterNum”,“functionChoice”等;
对于常量,所有的字母都大写,两个单词之间用下划线连接,如“MAX_CONTACER_LENGTH”,“MAX_NAME_LENGTH”。
在命名过程中尽量避免缩写,使用了完整的单词,更容易理解这个名字的含义。
欢迎界面,同时播放背景音乐
(2)程序的总体结构与说明
登录或注册
读取通讯录储存文件
输出主界面
添加联系人
保存数据退出程序
输出所有的联系人
修改联系人
删除联系人
查询联系人
(3)功能模块划分与描述
●欢迎界面:
界面是由PrintfFrame来输出边框,然后用textout来输出欢迎文字。
●主界面:
主界面是通过PrintfInterface来实现的。
在这个函数中调用PrintfMainMenu,PrintfFrame来实现。
●读取通讯录文件:
通过调用ReadContacter这个函数来读取通讯录所储存的文件addressbook.dat,每读取一个联系人,联系人数目contacterNum+1,最终结构就是返回联系人的数目,如果文件中没有任何联系人信息则contacterNum等于0。
●添加联系人:
通过调用AddOneContacter这个函数来添加一个联系人,添加时,按照名字,手机号码,联系地址,电子邮箱,QQ号码,最后选择分组的顺序录入。
如果没有该项信息则输入“#”,那么在以后输出这个联系人的信息时,“#”会转化为“暂时没有该项信息”。
添加后完成后会输出整个联系人的信息。
●查询联系人:
通过调用FindContacter来查找联系人,其中查找有三种实现方式,分别是:
联系人的姓名FindByName,联系人的地址FindByAddress,手机号码FindByPhone。
这三个函数调用后会返回查找到的联系人在整个数组中的下标是多少,然后通过调用PrintfOneContacter来输出该联系人的信息。
●删除联系人:
通过调用DeleteContacter来删除联系人,首先要求输入联系人的姓名,然后调用FindByName这个函数来查找联系人,然后是后面的联系人覆盖前面的联系人。
●修改联系人:
通过调用ChangeContacter这个函数来修改联系人。
修改时,同样,首先要求输入联系人的姓名,然后调用FindByName这个函数来查找联系人。
找到联系人后先输出该联系人的信息,后询问修改哪项内容,修改完成后在次调用PrintfOneContacter来输出修改后的联系人。
●输出所有的联系人:
通过调用PrintfAllContacter来实现。
首先选择输出的顺序,共六种,选择后通过调用相应的排序,来按顺序输出,此时,为了保持界面的外观,选择了用户通过“b”(返回),“u”(上一个),“n”(下一个)三个按键来控制输出的联系人。
●保存数据:
通过调用SaveContacter来将联系人的信息储存到addressbook.dat这个文件中。
2.数据结构
程序中用来储存联系人数据的是AddressBook这个结构体,其定义为:
typedefstructAddressBook
{
charname[MAX_NAME_LENGTH];
//名字
charphoneNumber[MAX_PHONE_LENGTH];
//手机号码
charcontactAddress[MAX_ADDRESS_LENGTH];
//联系地址
charemail[MAX_E_MAIL_LENGTH];
//电子邮箱
charqqNumber[MAX_QQ_LENGTH];
//QQ的号码
SortGroupgroup;
//分组
time_tsaveTime;
//保存时间
}AddressBook;
其中,SortGroup数据类型的定义为:
Typedefenum{Relative,Friend,Colleague,Schoolmate,Other}SortGroup;
//亲人,朋友,同事,同学,其他
用来储存用户的数据类型为:
typedefstructUser
charuserName[MAX_USER_NAME_LENGTH];
//用户名
charuserKey[MAX_USER_KEY_LENGTH];
//用户密码
}User;
3.函数原型声明的说明
●StatusAddOneContacter(AddressBookcontacter[],int*contacterNum,HANDLEhandle)
函数介绍:
添加联系人,添加后contacterNum+1
输入参数:
AddressBookcontacter[],int*contacterNum,HANDLEhandle
输出参数:
AddressBookcontacter[],int*contacterNum
返回值:
Status:
OK
●StatusChangeContacter(AddressBookcontacter[],intcontacterNum,HANDLEhandle)
修改联系人的信息
AddressBookcontacter[],intcontacterNum,HANDLEhandle
无
修改成功则返回OK
●StatusDeleteContacter(AddressBookcontacter[],int*contacterNum,HANDLEhandle)
删除一个联系人,删除后contacterNum-1
删除失败返回ERROR,成功返回OK
●intFindByAddress(AddressBookcontacter[],intcontacterNum)
通过住址查找,主要是让其他函数调用
AddressBookcontacter[],intcontacterNum
返回值i,如果i==contacterNum则找不到
●intFindByPhone(AddressBookcontacter[],intcontacterNum)
通过手机号码查找,主要是让其他函数调用
●intFindByName(AddressBookcontacter[],intcontacterNum)
通过姓名查找,主要是让其他函数调用
●StatusFindContacter(AddressBookcontacter[],intcontacterNum,HANDLEhandle)
寻找联系人
找不到返回ERROR,找到返回OK
●StatusPrintfAllContacter(AddressBookcontacter[],intcontacterNum,HANDLEhandle)
按一定的顺序输出所有联系人的信息
AddressBookcontacter[],intcontacterNum
有
●voidSortByTime(AddressBookcontacter[],intcontacterNum)
按添加的联系人时的时间排序,先添加的排在后面
AddressBookcontacter[]
●voidSortByName(AddressBookcontacter[],intcontacterNum)
按名字的拼音顺序从A~Z排序
●voidSortByAddress(AddressBookcontacter[],intcontacterNum)
按地址排序A~Z
●voidSortByPhone(AddressBookcontacter[],intcontacterNum)
按手机号码排序1~9
●voidSortByQq(AddressBookcontacter[],intcontacterNum)
按QQ号码排序0~9
●voidSortByGroup(AddressBookcontacter[],intcontacterNum)
按分组排序0~4
AddressBookcontacter[],intcontacterNum,UsermyUser
●StatusReadContacter(AddressBookcontacter[],int*contacterNum,UsermyUser)
从文件中读取所有联系人的信息,并用contacterNum统计联系人数目
AddressBookcontacter[],UsermyUser
int*contacterNum
写入成功返回OK,不成功返回ERROR
●StatusSaveContacter(AddressBookcontacter[],intcontacterNum,UsermyUser)
向文件中输入所有联系人的信息
●voidPrintfFrame(HANDLEhandle,intx,inttopY,intbuttomY)
输出边框
HANDLEhandle,intx(x轴起始坐标),
inttopY(顶部Y的坐标),intbuttomY(底部Y的坐标)
●intPrintfInterface(HANDLEhandle)
HANDLEhandle
返回功能选择functionChoice
●voidPrintfMainMenu(HANDLEhandle)
输出主目录
●voidPrintfOneContacter(AddressBookcontacter,HANDLEhandle)
输出一个联系人的信息
AddressBookcontacter,HANDLEhandle
●voidGoToXY(intx,inty)
设置光标的位置
intx,inty(光标的坐标x,y)
●StatusLogIn(HANDLEhandle,User*myUser)
登录
HANDLEhandle,User*myUser
User*myUser
登录成功返回OK,否则返回ERROR
●StatusRegister(HANDLEhandle,User*myUser)
注册
注册成功返回OK,否则返回ERROR
●StatusCheckUser(HANDLEhandle,User*myUser)
检查用户
注册或登录成功返回OK,退出返回ERROR
二、详细设计
1.main()
首先定义窗口句柄HANDLEhandle;
和联系人数组myAddress[MAX_CONTACER_LENGTH];
,其类型为AddressBook,联系人数组的最大值为MAX_CONTACER_LENGTH,而后定义模块功能选项intfunctionChoice=0,最后定义联系人数目contacterNum=0;
并定义文本颜色WORDwColors[2];
首先打开音乐文件后播放,然后初始化窗口,之后输出欢迎界面,然后读取联系人数据,若文件中没有联系人,则输出当前没有联系人的提示。
之后进入一个死循环,输出主目录,用switch来选择不同的功能。
当选择退出时则用return来退出。
其流程图为:
开始
打开音乐文件并播放音乐
①
初始化窗口
字符是否为空?
N
Y
break;
跳出循环
有按键按下?
输出欢迎界面文字
读取联系人
contacterNum
==0?
1?
NY
输出当前没有联系人
②Y
②
查看所有联系人
查找联系人
空
添加一个联系人
清屏
12345其他6
switch(functionChoice)
输出界面边框,并输出欢迎使用
functionChoice=PrintfInterface(handle)
输出界面并获得功能选项
保存联系人数据
设置光标位置
return0;
退出程序
结束
2.CheckUser函数
在这个函数中通过调用注册Register和登录LogIn两个函数来实现。
结束
returnOK;
LogIn(handle,myUser)==OK?
(handle,myUser
Register(handle,myUser)==OK?
Y①N
returnERROR
其他‘2’‘1’‘3’
switch(choice)
choice<
'
1'
||choice>
3'
?
重新输入choice
choice=_getch();
选择登录、注册或者退出
输出界面边框
3.AddOneContacter函数
用数组名contacter作为实参,可以改变数组的值,从而打到添加联系人的目的,而contacterNum是通过地址传递,也能够改变它的值从而是联系人数目加一。
添加时,按照名字,手机号码,联系地址,电子邮箱,QQ号码,最后选择分组的顺序录入。
如果没有该项信息则输入“#”
其流程图为:
输入分组
group<
1||group>
5?
输出边框及提示
输入姓名
选择分组switch(group)
输入手机号码
获取当前系统时间作为联系人的添加时间
输入联系地址
联系人数目加一
输入QQ号码
输出联系人信息
输入电子邮箱
4.ChangeContacter函数
用数组名contacter作为实参,可以改变数组的值,从而打到添加联系人的目的,而contacterNum因为不需要改变其值,故使用值传递的方法。
清屏并输出边框
输出该联系人的信息和提示信息
i=FindByName(contacter,contacterNum);
i==ontacterNum
输入想要修改的内容
输出没有该联系人并退出
根据changeItem不同的值选择相应的修改项目
修改完成后再次输出联系人的信息
5.DeleteContacter函数
用数组名contacter作为实参,可以改变数组的值,从而打到删除联系人的目的,而contacterNum删除后需要减一故采用传地址的方法。
首先查找联系人,如果查找到则删除,如果查找不到则输出没有该联系人。
其流程图为
i<
*contacterNum-1?
contacter[i]=contacter[i+1];
i++
*contacterNum=*contacterNum-1;
使联系热人数目减一
i==*contacterNum?
输出删除成功提示
6.FindContacter函数
总共有三种查找方式,分别是:
查找到了则输出该联系人的信息,查不到则输出没有该联系人。
switch(fineWay)
12其他3
i=FindByAddress(contacter,contacterNum);
i=FindByName(contacter,contacterNum);
输出选择目录
i=FindByPhone(contacter,contacterNum);
空
选择选择查找方式fineWay
i==contacterNum?
重新选择
fineWay<
1||fineWay>
4?
输出没有该联系人
输出该联系人的信息
7.PrintfAllContacter函数
输出时调用PrintfOneContacter函数。
根据printfWay的值选择排序的顺序
开始
contacterNum==0?
输出第一个联系人
输出上一个联系人
输出下一个联系人
return0
选择输出顺序
nu
switch(keyValue)
②其他b
输入printfWay
keyValue=_getch();
获取键值
是否有按键按下?
重新输入
printfWay<
1||printfWay>
7?
清除文字
①②
8.SaveContacter函数
首先打开addressbook.dat这个文件,为了提高写入速度,采用的是二进制的写入,如果写入不成功,返回ERROR
9.ReadContacter函数
采用二进制的只读方式打开addressbook.dat,每读取一个联系人,联系人数目加一,如果没有联系人则联系人数目为0。
Fread这个函数的返回值恰好是所读取的数据项的数目,只需要通过fread(&
contacter[*contacterNum],sizeof(AddressBook),1,filepoint)==1就可以判断是否全部读取,当读取完成时,fread的返回值为0,于是停止读取。
三、测试及调试
1.汉字排序问题:
其实这是最主要的一个问题,一