资源描述
课程名称 计算机高级语言课程设计(C)
教师姓名 刘 刚
本科生姓名 郭 勇 权
本科生学号 20121003468
本科生专业 机械设计制造及其自动化
所在院系 机 电 学 院
类别: C. 本科生
日期: 2013.7.11
课程设计评语
对课程论文的评语:
平时成绩:
课程论文成绩:
总 成 绩:
评阅人签名:
注:1、无评阅人签名成绩无效;
2、必须用钢笔或圆珠笔批阅,用铅笔阅卷无效;
3、如有平时成绩,必须在上面评分表中标出,并计算入总成绩。
目 录
1.题目要求 1
2.需求分析 1
3.总体设计 1
4.详细设计 2
5.上机操作 23
6.总结 28
7.致谢 28
参考文献 29
1.题目要求
模拟手机通信录管理系统,实现对手机中的通信录进行管理。功能要求如下:
(1)查看功能:选择此功能时,列出下列3类选择。
办公类.
个人类.
商务类.
当选中某类时,显示出此类所有数据中的姓名、电话号码和电子邮件。
(2)增加功能:能录入新数据。
一个结点包括:姓名、电话号码、分类(办公类、个人类、商务类)、电子邮件。
例如:
杨春135896664454商务类chuny@
当录入了重复的姓名和电话号码时,则提示数据录入重复并取消录入;当通信录中超过15条信息时,储存空间已满,不能再录入新数据;录入的新数据能按递增的顺序自动进行条目编号。
(3)修改功能:选中某个人姓名时,可对此人的相应数据进行修改。
(4)删除功能:选中某个人的姓名时,可对此人的相应数据进行删除,并自动调整后续条目的编号。
2.需求分析
根据题目要求,由于联系人信息时存放在文件中,所以应提供文件的输入、输出等操作;在程序中需要查看联系人信息,应提供显示、查看功能;要实现修改和删除联系人功能,所以应提供对文件的修改和删除操作。
3.总体设计
以下分析整个系统,根据上面的需求分析,可将这个系统的设计分为四大模块(如图一):
图一 系统功能模块图
4.详细设计
【详细设计】
1. 主函数
[程序]
main() /*******************主函数********************/
{
menu();
}
2. 主菜单
主菜单函数提供用户对系统功能的选择,包括浏览联系人、增加联系人、修改联系人、删除联系人。该函数的流程图如图二所示。程序如下。
开始
显示一系列功能选项
输入n,判断n是否是1-4?
Y
根据n的值调用各功能模块函数
结束
图二 主菜单流程图
[程序]
void menu() /******************菜单函数*****************/
{
int n=0,w1;
do
{
puts("\t\t***********************主菜单***********************\n\n");
puts("\t\t\t\t1. 查看联系人");
puts("\t\t\t\t2. 增加联系人");
puts("\t\t\t\t3. 修改联系人信息");
puts("\t\t\t\t4. 删除联系人");
puts("\n\n\t\t***************************************************\n");
printf(" (请选择1-4):[ ]\b\b");
scanf("%d",&n);
if(n<1||n>4)
{
w1=1;
getchar();
}
else
w1=0;
}while(w1==1);
switch(n)
{
case 1:browse();break; /*浏览联系人模块*/
case 2:add();break; /*增加联系人模块*/
case 3:modify();break; /*修改联系人模块*/
case 4:del();break; /*删除联系人模块*/
}
}
3.数据结构设计
各联系人信息包括有姓名、电话号码、联系人类型、电子邮件。可以使用结构体数组,则姓名、电话、类型和电子邮件作为结构体成员。
struct member /*联系人结构体*/
{
char name[20]; /*联系人姓名*/
char tel[11]; /*联系人电话*/
int type; /*联系人类型:1为办公类;2为个人类;3为商务类*/
char email[30]; /*联系人电子邮件*/
}mem[N]; /*N为全局变量,表示能够储存的联系人数量*/
4. 浏览联系人模块
[需求分析]
该模块的功能是使用户可以浏览或者分类浏览各联系人信息。如图三所示,当用户输入1、2、3、4时,分别显示办公类联系人、个人类联系人、商务类联系人和所有联系人。
图三 浏览联系人模块流程图
[程序]
void browse() /*********浏览联系人函数**********/
{
int m,n=0,w1;
m=load();
do
{
puts("\n\n\t\t ******************查询联系人********************");
puts("\t\t\t\t1. 查询办公类联系人"); /*查询办公类联系人*/
puts("\t\t\t\t2. 查询个人类联系人"); /*查询个人类联系人*/
puts("\t\t\t\t3. 查询商务类联系人"); /*查询商务类联系人*/
puts("\t\t\t\t4. 查询所有联系人"); /*查询所有联系人*/
puts("\t\t\t\t5. 返回主菜单 "); /*返回菜单*/
printf("请键入数字(1-5)选择:[ ]\b\b");
scanf("%d",&n);
if(n<1||n>5)
{
w1=1;
getchar();
}
else
w1=0;
}while(w1==1);
if(n==1)
{
printf_cle(m); /*显示办公类联系人*/
puts("\n信息已显示,按任意键返回菜单 \n");
system("pause"); /*暂停系统工作*/
getchar();
menu();
}
else if(n==2)
{
printf_per(m); /*显示个人类联系人*/
puts("\n信息已显示,按任意键返回菜单 \n");
system("pause"); /*暂停系统工作*/
getchar();
menu();
}
else if(n==3)
{
printf_com(m); /*显示商务类联系人*/
puts("\n信息已显示,按任意键返回菜单 \n");
system("pause"); /*暂停系统工作*/
getchar();
menu();
}
else if(n==4)
{
printf_all(m); /*显示商务类联系人*/
puts("\n信息已显示,按任意键返回菜单 \n");
system("pause"); /*暂停系统工作*/
getchar();
menu();
}
else
{
menu();
}
}
5. 增加联系人模块
[需求分析]
该模块的功能是使用户实现增加新联系人的功能,从键盘输入新联系人信息并加入到原文件中。该模块流程图如图四所示。
[程序]
void add()
{
int m,w1,n,t,w2,i,j; /*m为现有联系人数量*/
m=load(); /*加载联系人信息,并将联系人数量输入m*/
if(m==N)
{运行save(int)函数,将信息保存至文件中
是否保存?
输入联系人姓名、电话、类型、电子邮箱
判断m是否小
于N?
运行m=load()函数,加载现有联系人信息
开始
返回至主菜单
输出:储存空间已满,无法输入
Y
N
N
Y
结束
图四 增加联系人模块流程图
printf("储存空间不足!\n");
printf("按任意键返回菜单...");
getchar();
system("pause");
menu();
}
else
{
puts("\t请输入联系人姓名:"); /*输入联系人姓名*/
scanf("%s",mem[m].name); /*将联系人姓名保存至结构体*/
puts("\t请输入联系人电话号码:");
scanf("%s",mem[m].tel);
do /*选择联系人类型语句*/
{
puts("\n\n\n\n\n:\n\n\n请选择联系人类型");
puts("1, 办公类\t");
puts("2, 个人类\t");
puts("3. 商务类\t");
puts("请键入数字选择联系人类型:[ ]\b\b");
scanf("%d",&n);
if((n!=1)&&(n!=2)&&(n!=3))
{
w1=1;
getchar();
}
else
w1=0;
}while(w1==1);
switch(n) /*将联系人类型信息存入结构体中*/
{
case 1:mem[m].type=1;break;
case 2:mem[m].type=2;break;
case 3:mem[m].type=3;break;
}
puts("\t请输入联系人电子邮件地址:");
scanf("%s",mem[m].email);
}
do
{
puts("确定保存? 1.是 2.否[ ]\b\b");
scanf("%d",&t);
if(t<1||t>2)
{
w2=1;
getchar();
}
else
w2=0;
}while(w2==1);
if(t==1)
{
for(i=0;i<m;i++)
{
if(strcmp(mem[i].name,mem[m].name)==0)
{
puts("姓名已存在!不能存储,请按任意键返回菜单!");
for(j=0;j<20;j++)
mem[m].name[j]='\0';
for(j=0;j<11;j++)
mem[m].tel[j]='\0';
mem[m].type=0;
for(i=0;i<30;i++)
mem[m].email[j]='\0';
system("pause");
menu();
}
if(strcmp(mem[i].tel,mem[m].tel)==0)
{
puts("姓名已存在!不能存储,请按任意键返回菜单!");
for(j=0;j<20;j++)
mem[m].name[j]='\0';
for(j=0;j<11;j++)
mem[m].tel[j]='\0';
mem[m].type=0;
for(i=0;i<30;i++)
mem[m].email[j]='\0';
system("pause");
menu();
}
}
save(m); /*保存联系人信息至文本文档*/
puts("信息已存储!\n");
puts("以下是所有信:\n");
printf_all(m+1);
getchar();
puts("请按任意键返回菜单");
system("pause");
menu();
}
if(t==2) /*如果用户不保存,则将刚刚存入结构体中的数据删除*/
{
for(i=0;i<20;i++)
mem[m].name[i]='\0';
for(i=0;i<11;i++)
mem[m].tel[i]='\0';
mem[m].type=0;
for(i=0;i<30;i++)
mem[m].email[i]='\0';
puts("信息存储失败!\n");
puts(":以下是所有信息\n");
printf_all(m);
getchar();
puts("请按任意键返回菜单");
system("pause");
menu();
}
}
6. 修改联系人模块
[需求分析]
该模块的功能的功能是显示所有联系人信息。显示完后,用户输入要修改联系人的序号,系统根据用户输入的序号显示用户选择的联系人,并提示用户需要修改哪部分信息,是姓名、电话、类型还是电子邮箱。根据用户的选择修改相应的信息。
[程序]
void modify()
{
int m,n,t,w1,w2;
m=load();
puts("以下是所有信息:\t");
printf_all(m); /*显示所有信息,以便用户确认所要修改的信息*/
do
{
puts("请输入您想修改的联系人数字代号,或按0退出:");
scanf("%d",&n);
if(n<0||n>m)
{
w1=1;
getchar();
}
else
开始
w1=0;
运行m=load()函数,加载现有联系人信息,并显示所有用户信息
}while(w1==1);
if(n==0)
menu();
printf_one(n);
do
输入n
{
puts("\t\t\t\t1, 姓名");
puts("\t\t\t\t2. 电话号码");
判断n是否在0~15中
puts("\t\t\t\t3. 类型");
N
puts("\t\t\t\t4. 电子邮件");
puts("\t\t\t\t0. 退出");
Y
puts("请输入您想修改的类型数字代号,或按0退出:");
根据n的值调用相应功能模块
scanf("%d",&t);
if(t<0||t>4)
{
n是否等于0
w2=1;
getchar();
}
Y
else
N
w2=0;
输入t
}while(w2==1);
结束
返回至主菜单
调用相应功能模块
输入t
N
判断t是否在0~4中
Y
调用相应功能模块
返回至主菜单
结束
图五 修改联系人模块流程图
if(t==1)
modify_name(n,m); /*修改姓名函数,n为要修改的联系人编号;m为总联系人数*/
if(t==2)
modify_tel(n,m); /*修改电话函数,n为要修改的联系人编号;m为总联系人数*/
if(t==3)
modify_type(n,m); /*修改类型函数,n为要修改的联系人编号;m为总联系人数*/
if(t==4)
modify_email(n,m); /*修改Email函数,n为要修改的联系人编号;m为总联系人数*/
if(t==0)
menu();
}
7. 删除联系人模块
[需求分析]
该模块首先显示现有所有联系人,显示完成后,用户输入要删除的联系人序号。删除方式是将数据从结构体中删除,然后将后面的记录向前移。删除之后将记录保存至文件中。
[程序]
void del()
{
int m,n,w1,w2,t,i;
m=load();
puts("以下是所有信息:\t");
printf_all(m);
do
{
puts("请输入您想要删除的联系人数字代号:[ ]\b\b");
scanf("%d",&n);
if(n<0||n>m)
{
w1=1;
getchar();
}
else
w1=0;
}while(w1==1);
do /*用do while语句控制用户的输入,使用户只能输入1或者2*/
{
puts("您确定要删除此联系人:");
printf_one(n);
puts("\n您确定要删除吗? 1,是 2,否");
scanf("%d",&t);
开始
运行m=load();加载现有联系人信息;并显示所有联系人信息
输入要删除的联系人序号n
判断0﹤n≤m是否成立
N
Y
显示用户要删除的联系人的所有信息
用户是否确认
删除
N
Y
删除数据,并运行move函数,将删除位置后面的数据前移
运行save函数,将信息保存至文件中
返回至主菜单
结束
图六 删除联系人模块
if(t<1||t>2)
{
w2=1;
getchar();
}
else
w2=0;
}while(w2==1);
if(t==2)
{
puts("信息已保留,请按任意键反回菜单\n");
getchar();
system("pause");
menu();
}
if(t==1)
{
for(i=0;i<20;i++)
mem[n-1].name[i]='\0';
for(i=0;i<11;i++)
mem[n-1].tel[i]='\0';
mem[n-1].type=0;
for(i=0;i<30;i++)
mem[n-1].email[i]='\0';
move(n,m);
puts("信息已删除,请按任意键反回菜单\n");
getchar();
system("pause");
menu();
}
}
8. 公共函数
以下为各模块中可能用到的一些公共函数。
(1) 加载联系人信息函数:int load()
[说明]
该函数用于将文件中的数据加载至结构体中,并且可以返回现有联系人的数目。
[程序]
int load()
{
FILE *fp;
int i,j;
if((fp=fopen("E:\\vc programmes\\members.txt","rb"))==NULL)/*以只读方式打开一个二进制文件*/
{
printf("\n不能找到信息 ");
}
for(i=0;(!feof(fp))&&(i<N);i++)
fread(&mem[i],sizeof(struct member),1,fp);/*将文件中的数据加载至结构体中*/
fclose(fp); /*关闭文件*/
for(j=0;((strcmp(mem[j].name,"\0"))!=0)&&(j<N);j++);/*通过检测联系人姓名否为空来判断联系人数量*/
return(j); /*返回现有联系人数量*/
}
(2) 保存所有联系人函数:void save(int m)
[说明]
该函数形参m表示现有结构体中最后一个元素的下标。该函数主体如下
[程序]
void save(int m) /*m表示现有结构体中最后一个元素的下标*/
{
if(m==0) /*当m=0,即只有一个元素时,进入save_1函数,对文件进行只写操作*/
save_1();
else
{
save_1(); /*当m>0时,首先进入save_1函数,新建一个文件,同时把mem[0]的数据保存;然后进入save_2函数,将mem[1]到mem[m]的数据追加至文件中*/
save_2(m);
}
}
该包含两个子函数:void save_1()和void save_2(int m),当结构体中只有一个元素,即m=0时,只执行第一个函数,新建一个文件并将数据存入文件中;如果结构体中多于一个元素,即m>0时,首先执行第一个函数新建一个文件,然后执行第二个函数,将结构体中下标大于0的数据存入文件中。
[程序]
void save_1()
{
FILE *fp;
if((fp=fopen("E:\\vc programmes\\members.txt","wb"))==NULL)
{
printf("\n不能找到信息 ");
}
fwrite(&mem[0],sizeof(struct member),1,fp);
fclose(fp);
}
[程序]
void save_2(int m)
{
int i;
FILE *fp;
if((fp=fopen("E:\\vc programmes\\members.txt","ab"))==NULL)
{
printf("\n不能找到信息 ");
}
for(i=1;i<=m;i++)
fwrite(&mem[i],sizeof(struct member),1,fp);
fclose(fp);
}
(3) 显示所有联系人函数:void printf_all(int m)
[说明]
形参m表示现有联系人的数目。用以控制输出联系人的数量。该函数用于输出所有的联系人信息。
[程序]
void printf_all(int m)
{
int i;
printf("\n\n\t\t 以下是所有联系人 :");
printf("\n\nNO. 姓名 电话号码 类型 电子邮件 \n");
for(i=0;i<m;i++) /*判断联系人类别并输出*/
{
if(mem[i].type==1)
printf("%2d %-20s %-11s 办公类 %-30s\n",i+1,mem[i].name,mem[i].tel,mem[i].email);
if(mem[i].type==2)
printf("%2d %-20s %-11s 个人类 %-30s\n",i+1,mem[i].name,mem[i].tel,mem[i].email);
if(mem[i].type==3)
printf("%2d %-20s %-11s 商务类 %-30s\n",i+1,mem[i].name,mem[i].tel,mem[i].email);
}
}
(4) 显示办公类联系人函数:void printf_cle(int m)
[说明]
形参m表示现有联系人数目。用以控制循环终点。该函数用于输出所有办公类联系人信息。
[程序]
void printf_cle(int m)
{
int i;
printf("\n\n\t\t 办公类联系人:");
printf("\n\n姓名 电话号码 类型 电子邮件 \n");
for(i=0;i<m;i++)
if(mem[i].type==1) /*判断联系人是否属于办公类*/
printf("%-20s %-11s 办公类 %-30s\n",mem[i].name,mem[i].tel,mem[i].email);
}
(5) 显示个人类联系人函数:void printf_per(int m)
[说明]
形参m表示现有联系人数目。用以控制循环终点。该函数用于输出所有个人联系人信息。
[程序]
void printf_per(int m)
{
int i;
printf("\n\n\t\t 个人类联系人 :");
printf("\n\n姓名 电话号码 类型 电子邮件 \n");
for(i=0;i<m;i++)
if(mem[i].type==2) /*判断联系人是否属于个人类*/
printf("%-20s %-11s 个人类 %-30s\n",mem[i].name,mem[i].tel,mem[i].email);
}
(6) 显示商务类联系人函数:void printf_com(int m)
[说明]
形参m表示现有联系人数目。用以控制循环终点。该函数用于输出所有商务类联系人信息。
[程序]
void printf_com(int m)
{
int i;
printf("\n\n\t\t 商务类联系人:");
printf("\n\n姓名 电话号码 类型 电子邮件 \n");
for(i=0;i<m;i++)
if(mem[i].type==3) /*判断联系人是否属于商务类*/
printf("%-20s %-11s 商务类 %-30s\n",mem[i].name,mem[i].tel,mem[i].email);
}
(7) 显示某一联系人函数:void printf_one(int m)
[说明]
形参m表示现有联系人数目。用以控制循环终点。该函数用于输出某一指定联系人信息。
[程序]
void printf_one(int m)
{
printf("姓名 电话号码 类型 电子邮件 \n");
if(mem[m-1].type==1) /*三个if语句判断联系人类型*/
printf("%-20s %-11s 办公类 %-30s\n",mem[m-1].name,mem[m-1].tel,mem[m-1].email);
if(mem[m-1].type==2)
printf("%-20s %-11s 个人类 %-30s\n",mem[m-1].name,mem[m-1].tel,mem[m-1].email);
if(mem[m-1].type==3)
printf("%-20s %-11s 商务类 %-30s\n",mem[m-1].name,mem[m-1].tel,mem[m-1].email);
}
(8) 修改姓名函数:void modify_name(int n,int m)
[说明]
该函数用于修改联系人姓名。形参n为用户输入的要修改的联系人序号;m表示现有联系人数量。
[程序]
void modify_name(int n,int m)
{
char mod_name[20]; /*用于暂存用户输入的更改后的联系人姓名*/
int i,t,w1;
puts("请输入新姓名:");
scanf("%s",mod_name);
do
{
puts("确定要存储吗? 1.是 2.否 [ ]\b\b");
scanf("%d",&t);
if(t<1||t>2)
{
w1=1;
getchar();
}
else
w1=0;
}while(w1==1);
if(t==1)/*当用户输入1,即确认修改时,将原来存在结构体中联系人的姓名删除,并将新的联系人姓名赋到结构体中*/
{
for(i=0;i<20;i++)
mem[n-1].name[i]='\0';
strcpy(mem[n-1].name,mod_name);
save(m-1);
puts("储存成功,按任意键继续...");
getchar();
system("pause");
modify();
}
if(t==2)
{
for(i=0;i<20;i++)
mod_name[i]='\0';
puts("信息存储失败,按任意键继续...");
getchar();
system("pause");
modify();
}
}
(9) 修改电话函数:void modify_tel(int n,int m)
[说明]
该函数用于修改联系人电话。形参n为用户输入的要修改的联系人序号;m表示现有联系人数量。
[程序]
void modify_tel(int n,int m)
{
char mod_tel[11];
int i,t,w1;
puts("请输入新电话号码:");
scanf("%s",mod_tel);
do
{
puts("确定保存吗? 1.是 2.否 [ ]\b\b");
scanf("%d",&t);
if(t<1||t>2)
{
w1=1;
getchar();
}
else
w1=0;
}while(w1==1);
if(t==1)
{
for(i=0;i<11;i++)
mem[n-1].tel[i]='\0';
strcpy(mem[n-1].tel,mod_tel);
save(m-1);
puts("储存成功!按任意键继续...");
getchar();
system("pause");
modify();
}
if(t==2)
展开阅读全文