C语言通讯录程序设计与实现:数据添加、修改、查看、删除功能详解
手机通讯录系统 一、设计目的及要求 1.1 标题及设计要求

我们设计的程序是一个手机通讯录系统,用C语言编写。该程序与一般通讯录的功能相同,包括最基本的添加、修改、查看、删除数据的功能。设计该程序的目的是提高我们对C语言的整体掌握和应用。能够真正运用所学知识。
1.2 本程序涉及的知识点
If语句 switch语句 for循坏 do…while循坏 goto语句
二维数组 指针 字符串复制比较等 文件操作 结构体 函数的套用
2 功能设计 2.1 总体设计
整个系统可以设计为用于文件读写的数据添加模块、数据修改模块、数据删除模块和数据查看模块。如图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;b1;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/*把删除位置以后的所有数据向前移动一位*/
{ 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.1 显示所有记录 4.2 添加功能
此功能允许您按顺序添加信息。选择主菜单下的“2 添加”。程序会先判断文件中有多少条数据,然后从末尾添加。每添加一条记录后,都会提示是否继续添加。如果选择1是,则会继续按顺序添加。如果选择 2 否,您将返回主菜单。程序运行结果如图4.2所示。
图 4.2 添加记录 4.3 插入功能
该函数可以在任意位置插入记录。在主菜单下选择3即可进入该功能。首先,用户选择要插入的位置,然后输入数据。输入完成后,这里记录的所有数据都会向后移动一位。这是实现的。数据插入。也返回主菜单。程序运行结果如图4.3所示。
图 4.3 插入信息 4.4 修改功能
该功能允许修改数据。在主菜单下选择4,进入修改功能。首先,会要求用户搜索想要修改的记录,通过搜索名称找到该记录,然后重新输入新信息修改数据,同时返回主菜单。程序运行结果如图4.4所示。
图 4.4 修改记录 4.5 删除功能
该功能可以实现数据的删除。选择主菜单下的5.删除,进入删除功能。首先,将进入二级菜单,允许用户选择删除方法。如果选择1.删除指定条数的记录,会要求用户输入要删除的记录,按回车确认删除,并提示“删除成功!”并返回主菜单。程序运行结果如图4.5.1所示。该算法通过将删除后的所有数据向前移动一位来实现删除。如果在二级菜单中,用户选择2全部删除,为了防止误删除,三级菜单设置为确认删除。如果选择1,则删除所有记录,并提示“删除成功!”会提示返回主菜单。选择 2. 否返回主菜单而不删除。程序运行结果如图4.5.2所示。
图4.5.1 按指定条数删除
图4.5.2 删除全部4.6查询功能
该功能可实现数据搜索。选择主菜单下的“6.查询”,进入查询菜单。如果选择“1.按姓名查询”,则会要求用户输入要查询的姓名,然后显示该人的所有信息并返回主菜单。此功能将输入的名称与所有数据进行比较。如果有则查找成功并输出。如果没有,会提示没有此人的记录。程序运行结果如图4.6.1所示。在查询菜单下,还设置了2.按类别查询。进入该功能后,会要求用户选择要查询的类别:1.办公类别,2.个人类别,3.商务类别。选择相应的序号将显示该类别中的所有记录。如果对应类别没有记录,则提示“无此记录!”。程序运行结果如图4.6.2
图4.6.1 按名称查询
图 4.6.2 按类别查询 4.7 退出系统
选择主菜单下的“7.保存并退出”,保存数据并退出系统。程序运行结果如图4.7所示。
图 4.7 保存退出 5. 小结
从接到这个任务起,我们就开始计划这个小组。他们对于完成这次任务非常有信心。这是用来验证我们上学期的学习成果。一开始我们查阅了一些资料,划分了工作。我们首先讨论了整个程序的框架,然后开始各自完成自己的模块。最后我们整合了。这也是最关键、最困难的一步。在这个过程中我们遇到了很多问题。比如变量不统一;文件指针是全局声明的;文件读写也存在很多问题,无法准确读取文件中有多少记录。我们团队成员对这些问题进行了讨论,经过一次又一次的调试,我们终于想出了一个好的方案。通过解决问题,我们对C语言有了更深入的了解。能够熟练运用以前所学的知识。通过这个小组模式,我们感受到了小组成员之间团结协作的重要性。这对我们以后的生活也有很大帮助。以后我们还会继续合作学习C语言。一起学习,一起进步。
6.所有代码
#include
#include
#include
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;istrcpy(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