手机通讯录系统
1、设计目的与要求
1.1题目与设计要求
我们设计的程序为手机通讯录系统,这是使用C语言写成。本程序具有和一般的通讯录一样的功能,有最基本的数据添加、修改、查看、删除等功能。通过对程序的设计的目的是为了提高我们对C语言的整体把握与应用。能把学会的知识真正的会应用。
1.2 本程序涉及的知识点
If语句 switch语句 for循坏 do…while循坏 goto语句
二维数组 指针 字符串复制比较等 文件操作 结构体 函数的套用
2、功能设计
2.1 总体设计
整个系统可以设计为数据添加模块、数据修改模块、数据删除模块、数据查看模块文件写入与读取。如图1所示.
2.2 详细设计
(1)数据添加模块
首先,查看信息条数是否超过15,如果超过,则提示“通信录已满!”,返回上级菜单;否则,从通讯录末尾开始顺序添加信息。每添加完一条记录,都会询问是否继续添加。如果是,则继续添加。否则返回主菜单。同时把所有数据重新写入文件。
(2)数据修改模块
修改通信录信息,则需要读文件。然后选择要修改的信息,进行修改。修改完毕后,所有数据重新写入文件。且返回主菜单。
(3)数据删除模块
通过菜单选择删除操作。在删除模块中我们设置了两个选项。删除指定数据和全部删除。若选择删除指定数据,则会提示输入要删除的条数,然后删除。若选择删除全部记录,则会把所有记录清空。每次操作完后,都会重新把数据写入文件并返回主菜单。
(4)数据查看模块
通过菜单选择查看信息,可以选择按姓名查看,或者按类别查看。选择按姓名查找则会显示对应的姓名信息。如果选择按类别查看,则可以选择办公类、个人类或者商务类,然后会显示所选类信息列表。这是一个查找与显示的过程,在手机通信录文件中通过比对查找相应类型符合的记录,并输出。
(5)文件的写入与读取
首先每次运行程序,都会先检测“通讯录”文件是否存在。若存在,则先读取文件。若不存在,则会先新建一个空白文件。然后在每次操作后都会重新把数据写入文件。确保了数据的安全性。防止程序意外退出或电脑断电等造成数据丢失。
3、程序实现
3.1 程序实现时应考虑的问题
每次操作后回到主菜单
如何实现退出
- 每次操作后如何把数据写入文件
- 读取文件时如何统计数据条数
- 实现多级菜单
- 如何实现全部删除
- 如何实现分类查询
3.2任务分工及源代码说明
曹世宏 负责:文件的写入和读取,以及对整个程序的整合调试
在我设计此段代码时我遇到了很多问题,首先是在程序运行时就要读取文件信息,因为刚开始做的为只读方式,所以如果没有文件就会出错,后来经过改正,没有文件的话就新建一个空白文件,这个问题就解决了。在写文件上,刚开始能把数据都写写进去,但只要重新修改程序中的数据后,原来的数据就没了。经过我的反复调试检查发现,是因为每次写入文件是没有记录写进了几条数据,所以导致每次读取出错。经过改正,在每次写文件时先把数据总数写进去再写其他数据,在每次读取时,先读取有几条数据,作为判断条件,然后就能按顺序都能读取出来。最后都调试好后,考虑到文件的安全性,我在每次调用其他函数后都会写一次数据,防止数据的丢失。
文件读取:
void Fread()/*读取文件*/
{ if((fp=fopen("通讯录.text","r+"))==NULL)
{ return; }
fread(&j,sizeof(int),1,fp);
for(i=1;i<=j;i++)
{fread(&friends[i],sizeof(struct Friend),1,fp); }
fclose(fp);
}
文件写入:
void Fwrite()/*写入文件*/
{ if((fp=fopen("通讯录.text","w+"))==NULL)
{printf("不能打开这个文件!\n");return; }
fwrite(&j,sizeof(int),1,fp);
for(i=1;i<=j;i++)
{ fwrite(&friends[i],sizeof(struct Friend),1,fp); }
fclose(fp);
}
程文辉 负责:数据查看模块
查看输出:
void Date_output(int i)/*信息输出*/
{
printf("第%d条记录\n",i);
printf("姓名:%s\n",friends[i].name);
printf("电话号码:%s\n",friends[i].tel);
printf("联系人所属类别(1:办公类 2:个人类 3:商务类):%d\n",friends[i].type);
printf("生日:%d/%d/%d\n",friends[i].Brithday.month,friends[i].Brithday.month,friends[i].Brithday.day);
printf("e-mail:%s\n",friends[i].email);
printf("地址:%s\n",friends[i].addr);
}
信息查询:
void Search()/*按姓名查询功能*/
{ int a=0;
char names[20];/*定义临时姓名*/
printf("请输入要查询的人名:\n");
scanf("%s",&names);
for(i=1;i<=j;i++)
{ if(strcmp(names,friends[i].name)==0)/*对比姓名是否一致*/
{ Date_output(i); a=1; break; }
}
if(a!=1)
printf("没有此记录!\n");
printf("\n\n");
}
void Lei_search()/*按类别查询*/
{ struct Friend people[10];/*定义临时结构体数组*/
int b=0; int c,d;/*c 存放临时数据 d:统计一个类别有多少人*/
printf("\t\t请输入要查询的类别\n");
printf("\t\t\t1:办公类\n\t\t\t2:个人类\n \t\t\t3:商务类\n ");
scanf("%d",&c);
for(i=1;i<=j;i++)
{ if(friends[i].type-c==0)
{ people[b]=friends[i]; b++;d=b; }
}
if(b!=0)
{ for(b=1;b<d+1;b++)
{Date_output(b); }
}
else
printf("此类别没有记录!\n");
printf("\n");
}
程兴旺 负责:数据添加模块、数据删除模块
信息添加:
void Insert()/*插入记录函数*/
{ printf("请输入要插入的位置:第()位\n");
scanf("%d",&k);
for(i=j+1;i>k;i--)/*把插入位置以后的所有数据向后移动一位*/
{
strcpy(friends[i].name,friends[i-1].name);
strcpy(friends[i].tel,friends[i-1].tel);
friends[i].type=friends[i-1].type;
friends[i].Brithday.year=friends[i-1].Brithday.year;
friends[i].Brithday.month=friends[i-1].Brithday.month;
friends[i].Brithday .day=friends[i-1].Brithday.day;
strcpy(friends[i].email,friends[i-1].email);
strcpy(friends[i].addr,friends[i-1].addr);
}
Date_Input(k); j++;rintf("\n\n");
}
信息删除:
void Delete()/*删除指定记录*/
{ printf("请输入要删除的位置:第()位\n");
scanf("%d",&k);
for(i=k;i<j;i++)/*把删除位置以后的所有数据向前移动一位*/
{ strcpy(friends[i].name,friends[i+1].name);
strcpy(friends[i].tel,friends[i+1].tel);
friends[i].type=friends[i+1].type;
friends[i].Brithday.year=friends[i+1].Brithday.year;
friends[i].Brithday.month=friends[i+1].Brithday.month;
friends[i].Brithday .day=friends[i+1].Brithday.day;
strcpy(friends[i].email,friends[i+1].email);
strcpy(friends[i].addr,friends[i+1].addr);
}
j--;
printf("\n\n");
}
董泽琦 负责:数据修改模块
void Xiugai()/*修改信息*/
{ char names[20];
int m=0;
printf("请输入要修改的姓名:\n");
scanf("%s",names);
for(i=1;i<=j;i++)
{ if(strcmp(names,friends[i].name)==0)/*比较姓名*/
{ Date_Input(i); break; }
else
{m++;}
}
if(m==j)
printf("没有此记录!\n");
printf("\n\n");
4、程序测试结果
4.1显示所有记录
这个功能可以显示出所有的已经存储在文件中的记录,在菜单选项中选择1,就会显示出所有记录。程序运行结果如 图4.1
4.2添加功能
这个功能可以实现顺序添加信息。在主菜单下选择2添加,程序首先会判断文件中有几条数据,然后能从末尾开始添加,在每次添加完记录后,会提示是否继续添加。若选择1是,则会按顺序继续添加。若选择2否,则会返回主菜单。程序运行结果如图4.2。
4.3插入功能
这个功能可以实现在任何位置插入记录。在主菜单下选择3,就会进入此功能,首先会然用户选择想要插入的位置,然后进行数据输入,输入完成后,在此记录以后的所有数据向后移动一位,这就实现了数据插入。同时返回主菜单。程序运行结果如图4.3。
4.4修改功能
这个功能可以实现对数据的修改。在主菜单下选择4,就会进入修改功能,首先会让用户查找想要修改的记录,通过查找姓名找出此记录,然后重新输入新的信息实现对数据的修改,同时返回主菜单。程序运行结果如图4.4。
4.5删除功能
这个功能可以实现对数据的删除。在主菜单下选择5.删除,就会进入删除功能。首先会进入二级菜单,让用户选择删除的方式。若选择1.按指定条数删除,则会让用户输入要删除的记录,回车确认删除,提示“删除成功!”并返回主菜单,程序运行结果如图4.5.1。此算法通过让删除以后的所有数据向前移动一位来实现删除。 若在二级菜单下,用户选择2全部删除,为了方式误删,是设置了三级菜单是否确认删除,选择1是,则所有记录删除,提示“删除成功!”返回主菜单。选择2.否,则不删除直接返回主菜单。程序运行结果如 图4.5.2.
4.6查询功能
这个功能可以实现对数据的查找。在主菜单下选择6.查询,会进入查询菜单,若选择1.按姓名查询,则会让用户输入要查询的姓名,并显示出此人所有信息,同时返回主菜单。此功能是通过输入的姓名与所有数据进行对比,如果有则查找成功输出,如果没有则提示没有此人记录。程序运行结果如下图4.6.1。在查询菜单下,还设置了2.按类别查询。进入此功能后会让用户选择要查询的类别1.办公类,2. .个人类,3商务类。选择相应的序号会显示出此类别的所有记录,若没有相应类别记录会提示“没有此类记录!”。程序运行结果如下图4.6.2
4.7退出系统
在主菜单下选择7.保存并退出,会保存数据并退出系统。程序运行结果如 图4.7。
5、总结
从拿到这个作业时,我们规划好了小组。都很有信心去完成这个作业。以此来验证我们上一学期的学习成果。在开始时,我们查阅了一些资料并且进行了分工。我们先讨论了整个程序的框架,然后各自开始去完成自己的模块。在最后我们进行了整合。这也是最关键最难得一步。在这个过程中我们遇到了很多问题。比如,变量不统一;文件指针全局声明;还有在文件读写方面出现了许多问题,不能准确读取文件中有几个记录等。对于这些问题我们小组成员进行了讨论,经过一次次的调试,最终终于程序很好的做了出来。通过解决问题,我们更加深了对C语言的认识。对于以前学到的知识能熟练地运用。通过这次的小组模式,我们更感受到了小组成员团结合作的重要性。这将在以后的生活中也对我们有很大帮助。在今后我们将继续合作学习研究C语言。共同学习,共同进步。
6、全部代码
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
FILE*fp;
int j=1,i,k;/*i:第几人 j:总人数 k:指定数*/
int n;/*统计文件个数*/
struct Brithday
{
int year;
int month;
int day;
};
struct Friend
{
int num;
char name[20];
char tel[13];
int type;/*1:办公类 2:个人类 3:商务类*/
struct Brithday Brithday;
char email[20];
char addr[20];
}friends[15];
int main()
{
void Date_Input(int i);/*输入信息*/
void Date_output(int i);/*输出信息*/
void Insert();/*插入信息*/
void Delete();/*删除指定记录*/
void Search();/*按姓名查询*/
void Xiugai();/*修改信息*/
void Fwrite();/*写入文件*/
void Fread();/*读取文件*/
void Mean();/*主菜单*/
void Lei_search();/*按类别查询*/
Fread();
do
{
char s;
E:
Mean();
scanf("%s",&s);
switch(s)
{
case '1':
system("cls");
if((fp=fopen("通讯录.text","r+"))==NULL)
{
printf("不能打开这个文件!\n");
return;
}
fread(&j,sizeof(int),1,fp);
if(j>=1)
{
for(i=1;i<=j;i++)
{
Date_output(i);
printf("\n");
}
}
else
printf("没有记录!\n\n");
break;
case '2':
system("cls");
C:
printf("请添加记录:\n");
for(i=j+1;i<15;i++)
{
Date_Input(i);
j++;
Fwrite();
printf("\t是否继续插入\n");
printf("\t\t1:是 \n");
printf("\t\t2:否\n");
D:
scanf("%d",&k);
if(k==1)
{
goto C;
printf("\n");
}
else if(k==2)
goto E;
else
{
printf("请输入1-2!\n");
goto D;
}
}
case '3':
system("cls");
{
Insert();
Fwrite();
break;
}
case '4':
system("cls");
{
Xiugai();
Fwrite();
break;
}
case '5':
system("cls");
{
printf("\t请选择删除的方式\n");
printf("\t\t1:删除指定条数 \n");
printf("\t\t2:全部删除\n");
F:
scanf("%d",&k);
if(k==1)
{
Delete();
Fwrite();
printf("删除成功!\n");
printf("\n");
break;
}
else if(k==2)
{
R:
printf("\t\t\t是否确认删除\n\t\t\t1.是\n\t\t\t2.否\n");
int s=0;
scanf("%d",&s);
if(s==1)
{
j=0;Fwrite();
printf("删除成功!\n");
break;
}
else if(s==2)
break;
else
goto R;
break;
}
else
{
printf("请输入1-2!\n");
goto F;
}
break;
}
case '6':
system("cls");
{
B:
printf("\t请输入查询的方式\n");
printf("\t\t1:按姓名查询 \n");
printf("\t\t2:按类别查询\n");
scanf("%d",&k);
if(k==1)
{
Search();
printf("\n");
break;
}
else if(k==2)
{
Lei_search();
printf("\n");
break;
}
else
{
printf("请输入1-2!\n");
goto B;
}
break;
}
case '7':
{
printf("按任意键退出!");
Fwrite();
goto A;
}
default:printf("输入错误!\n");
}
}while(6);
A:
return 0;
}
void Mean()/*主菜单*/
{
printf("\n\t主菜单功能选择:\n");
printf("\t1:显示所有记录\n");
printf("\t2:添加\n");
printf("\t3:插入\n");
printf("\t4:修改\n");
printf("\t5:删除\n");
printf("\t6:查询\n");
printf("\t7:保存并退出\n");
}
void Date_Input(int i)/*信息录入*/
{
friends[i].num=i;
printf("第%d条记录\n",i);
printf("请输入姓名:\n");
scanf("%s",friends[i].name);
printf("请输入电话号码\n");
scanf("%s",friends[i].tel);
printf("请输入联系人所属类别(输数字(1:办公类 2:个人类 3:商务类)):\n");
scanf("%d",&friends[i].type);
printf("请输入生日(年):\n");
scanf("%d",&friends[i].Brithday.year);
printf("请输入生日(月):\n");
scanf("%d",&friends[i].Brithday.month);
printf("请输入生日(日):\n");
scanf("%d",&friends[i].Brithday.day);
printf("请输入e-mail地址:\n");
scanf("%s",friends[i].email);
printf("请输入地址:\n");
scanf("%s",friends[i].addr);
}
void Date_output(int i)/*信息输出*/
{
printf("第%d条记录\n",i);
printf("姓名:%s\n",friends[i].name);
printf("电话号码:%s\n",friends[i].tel);
printf("联系人所属类别(1:办公类 2:个人类 3:商务类):%d\n",friends[i].type);
printf("生日:%d/%d/%d\n",friends[i].Brithday.year,friends[i].Brithday.month,friends[i].Brithday.day);
printf("e-mail:%s\n",friends[i].email);
printf("地址:%s\n",friends[i].addr);
}
void Insert()/*插入记录函数*/
{
printf("请输入要插入的位置:第()位\n");
scanf("%d",&k);
for(i=j+1;i>k;i--)
{
strcpy(friends[i].name,friends[i-1].name);
strcpy(friends[i].tel,friends[i-1].tel);
friends[i].type=friends[i-1].type;
friends[i].Brithday.year=friends[i-1].Brithday.year;
friends[i].Brithday.month=friends[i-1].Brithday.month;
friends[i].Brithday .day=friends[i-1].Brithday.day;
strcpy(friends[i].email,friends[i-1].email);
strcpy(friends[i].addr,friends[i-1].addr);
}
Date_Input(k);
j++;
printf("\n\n");
}
void Delete()/*删除指定记录*/
{
printf("请输入要删除的位置:第()位\n");
scanf("%d",&k);
for(i=k;i<j;i++)
{
strcpy(friends[i].name,friends[i+1].name);
strcpy(friends[i].tel,friends[i+1].tel);
friends[i].type=friends[i+1].type;
friends[i].Brithday.year=friends[i+1].Brithday.year;
friends[i].Brithday.month=friends[i+1].Brithday.month;
friends[i].Brithday .day=friends[i+1].Brithday.day;
strcpy(friends[i].email,friends[i+1].email);
strcpy(friends[i].addr,friends[i+1].addr);
}
j--;
printf("\n\n");
}
void Search()/*按姓名查询功能*/
{
int a=0;
char names[20];
printf("请输入要查询的人名:\n");
scanf("%s",&names);
for(i=1;i<=j;i++)
{
if(strcmp(names,friends[i].name)==0)
{
Date_output(i);
a=1;
break;
}
}
if(a!=1)
printf("没有此记录!\n");
printf("\n\n");
}
void Lei_search()/*按类别查询*/
{
struct Friend people[10];
int b=0;
int c;
printf("\t\t请输入要查询的类别\n");
printf("\t\t\t1:办公类\n");
printf("\t\t\t2:个人类\n");
printf("\t\t\t3:商务类\n");
scanf("%d",&c);
for(i=1;i<=j;i++)
{
if(friends[i].type==c)
{
Date_output(i);
b=1;
}
}
if(b!=1)
printf("此类别没有记录!\n");
printf("\n");
}
void Xiugai()/*修改信息*/
{
char names[20];
int m=0;
printf("请输入要修改的姓名:\n");
scanf("%s",names);
for(i=1;i<=j;i++)
{
if(strcmp(names,friends[i].name)==0)
{
printf("查找成功,请进行修改:\n");
Date_Input(i);
break;
}
else
{
m++;
}
}
if(m==j)
printf("没有此记录!\n");
printf("\n\n");
}
void Fwrite()/*写入文件*/
{
if((fp=fopen("通讯录.text","w+"))==NULL)
{
printf("不能打开这个文件!\n");
return;
}
fwrite(&j,sizeof(int),1,fp);
for(i=1;i<=j;i++)
{
fwrite(&friends[i],sizeof(struct Friend),1,fp);
}
fclose(fp);
}
void Fread()/*读取文件*/
{
if((fp=fopen("通讯录.text","r+"))==NULL)
{
printf("不能打开这个文件!\n");
return;
}
fread(&j,sizeof(int),1,fp);
for(i=1;i<=j;i++)
{
fread(&friends[i],sizeof(struct Friend),1,fp);
}
fclose(fp);
}
参考文献
[1]谭浩强著. C程序设计(第四版).北京:清华大学出版社,2010.6