在上一节我们基本了解了顺序表的基本知识,接下来我们就用顺序表来实现一下通讯录。
一、基于动态顺序表实现通讯录
1.1 功能介绍
1. 能够保存用户信息:姓名,性别,年龄,电话,地址等
2. 添加联系人信息
3. 删除指定联系人
4. 查找指定联系人
5. 修改联系人信息
6.显示联系人信息
1.2 思路分析
我们之前创建的顺序表可以实现连续存储数据(类型可以为整型、字符等),但无论是哪种类型,存储信息都比较单一,但是通讯录存储信息比较多,有联系人姓名、性别、年龄等,所以我们把一个联系人的所有信息作为一个整体存储到顺序表,原来我们写的是整型作为数据存储每个数组元素空间,现在转化通讯录,把一个人的所有信息打包变为结构体然后存储到数组元素元素的空间,然后基于顺序表实现通讯录功能。
1.3 通讯录的实现
因为我们是在动态顺序表的前提下来实现通讯录的,所以我们先把顺序表中要用到的内容写好
1.3.1顺序表
1.3.1.1SeqList.h
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "Contact.h"
//动态顺序表
typedef peoInfo SLDatatype;//peoInfo就是下面要讲的通讯录联系人的信息结构体
typedef struct SeqList
{
SLDatatype *a;
int size;
int capacity;
}SL;
void SLInit(SL* psl);
void SLDestroy(SL* psl);
void SLPrint(SL* psl);
//STL命名风格
void SLPushBack(SL* psl,SLDatatype x);
void SLPushFront(SL* psl,SLDatatype x);
void SLPopBack(SL* psl);
void SLPopFront(SL* psl);
void SLInsert(SL* psl,int pos,SLDatatype x);
void SLErase(SL* psl,int pos);
int SLFind(SL* psl,SLDatatype x);
void SLModify(SL* psl,int pos,SLDatatype x);
1.3.1.2 SeqList.c
#include "SeqList.h"
void SLInit(SL* psl)
{
psl->a=(SLDatatype*) malloc(sizeof(SLDatatype)*4);
if(psl->a==NULL)
{
perror("malloc fail");
return;
}
psl->capacity=4;
psl->size=0;
}
void SLDestroy(SL* psl)
{
free(psl->a);
psl->a=NULL;
psl->size=0;
psl->capacity=0;
}
void SLCheckCapacity(SL* psl)
{
if(psl->size==psl->capacity)
{
SLDatatype* tmp=(SLDatatype*)realloc(psl->a,sizeof(SLDatatype)*psl->capacity*2);
if(tmp==NULL)
{
perror("realloc fail");
return;
}
psl->a=tmp;
psl->capacity*=2;
}
}
void SLPushBack(SL* psl,SLDatatype x)
{
SLCheckCapacity(psl);
psl->a[psl->size++]=x;
}
void SLPushFront(SL* psl,SLDatatype x)
{
SLCheckCapacity(psl);
int end=psl->size-1;
while(end>=0)
{
psl->a[end+1]=psl->a[end];
-end;
}
psl->a[0]=x;
psl->size++;
}
void SLPopBack(SL* psl)
{
if(psl->size==0)
return;
psl->size--;
}
void SLPopFront(SL* psl)
{
assert(psl->size>0);
int start=0;
while (start<psl->size-1)
{
psl->a[start]=psl->a[start+1];
start++;
}
psl->size--;
}
void SLInsert(SL* psl,int pos,SLDatatype x)
{
assert(psl);
assert(0<=pos && pos<=psl->size);
SLCheckCapacity(psl);
int end=psl->size-1;
while(end >= pos)
{
psl->a[end+1]=psl->a[end];
--end;
}
psl->a[pos]=x;
psl->size++;
}
void SLErase(SL* psl,int pos)
{
assert(psl);
assert(0<=pos && pos<psl->size);
int start=pos+1;
while(start<psl->size)
{
psl->a[start-1]=psl->a[start];
++start;
}
psl->size--;
}
void SLModify(SL* psl,int pos,SLDatatype x)
{
assert(psl);
assert(0<=pos && pos<psl->size);
psl->a[pos]=x;
}
1.3.2 通讯录的实现
1.3.2.1通讯录头文件,Contact.h
首先定义联系人数据
#define NAME_MAX 20
#define GENDER_MAX 10
#define TEL_MAX 20
#define ADDR_MAX 100
//定义联系人数据 结构
//姓名 性别 年龄 电话 地址
typedef struct personInfo
{
char name[NAME_MAX];
char gender[GENDER_MAX];
int age;
char tel[TEL_MAX];
char addr[ADDR_MAX];
}peoInfo;
由于要用到顺序表相关的方法,对通讯录的操作实现实际上是对顺序表进行操作
所以给顺序表结构体改个名字
typedef struct SeqList Contact;
接下来先声明通讯录相关的方法
//通讯录的初始化
void ContactInit(Contact* con);
//通讯录的销毁
void ContactDesTroy(Contact* con);
//通讯录添加数据
void ContactAdd(Contact* con);
//通讯录删除数据
void ContactDel(Contact* con);
//通讯录的修改
void ContactModify(Contact* con);
//通讯录查找
void ContactFind(Contact* con);
//展示通讯录数据
void ContactShow(Contact* con);
1.3.2.2通讯录初始化和销毁
通讯录的初始化和销毁实际上就是顺序表的初始化和销毁
//通讯录的初始化
void ContactInit(Contact* con)
{
SLInit(con);
}
//通讯录的销毁
void ContactDesTroy(Contact* con)
{
SLDestroy(con);
}
1.3.2.3通讯录联系人的添加
//通讯录添加数据
void ContactAdd(Contact* con)
{
peoInfo info;
printf("请输入要添加的联系人姓名:\n");
scanf("%s",info.name);
printf("请输入要添加的联系人性别:\n");
scanf("%s",info.gender);
printf("请输入要添加的联系人年龄:\n");
scanf("%d",info.&age);
printf("请输入要添加的联系人的电话:\n");
scanf("%s",info.tel);
printf("请输入要添加的联系人的住址:\n");
scanf("%s",info.addr);
SLPushBack(con,info);//将联系人信息结构体存入顺序表中
}
1.3.2.4删除联系人
删除联系人之前,我们先写一个通过名字在通讯录查找是否有此人,如果有就返回他是第几位,如果没有就返回一个-1.(也可以是通过其他方法比如年龄,性别,电话等等,根据自己的喜好)
int FindByName(Contact *con,char name[])
{
for(int i=0;i<con->size;i++)
{
if(strcmp(con->a[i].name,name)==0)
return i;
}
return -1;
}
接下来就来实现删除联系人,首先需要判断要删除的联系人是否在通讯录中。如果没有就输出“您要删除的联系人不再通讯录中”来提醒操作者,接下来是代码实现
//通讯录删除数据
void ContactDel(Contact* con)
{
char name[NAME_MAX];
printf("请输入您要删除的联系人姓名:\n");
scanf("%s",name);
int find= FindByName(con,name);
if(find<0)
{
printf("您要删除的联系人不在通讯录内!\n");
return;
}
SLErase(con,find);
printf("删除成功!\n");
}
1.3.2.5修改联系人信息
依然跟删除联系人一样,需要先判断是否存在此人,再进行修改
//通讯录的修改
void ContactModify(Contact* con)
{
printf("请输入您要修改的联系人姓名:\n");
char name[NAME_MAX];
scanf("%s",name);
int find= FindByName(con,name);
if(find<0)
{
printf("您要修改的联系人不存在!\n");
return;
}
printf("请输入新的姓名:");
scanf("%s",con->a[find].name);
printf("请输入新的性别:");
scanf("%s",con->a[find].gender);
printf("请输入新的年龄:");
scanf("%d",con->a[find].age);
printf("请输入新的电话:");
scanf("%s",con->a[find].tel);
printf("请输入新的住址:");
scanf("%s",con->a[find].addr);
printf("修改成功!\n");
}
1.3.2.6通讯录查找
//通讯录查找
void ContactFind(Contact* con)
{
char name[NAME_MAX];
printf("请输入您要查找的联系人姓名:\n");
scanf("%s",name);
int find= FindByName(con,name);
if(find<0)
{
printf("您要查找的联系人不在通讯录内!\n");
return;
}
printf("%s %s %s %s %s \n","姓名","性别","年龄","电话","地址");
printf("%3s %3s %3d %3s %3s\n",
con->a[find].name,
con->a[find].gender,
con->a[find].age,
con->a[find].tel,
con->a[find].addr
);
}
1.3.2.7通讯录展示
//展示通讯录数据
void ContactShow(Contact* con)
{
printf("%s %s %s %s %s \n","姓名","性别","年龄","电话","地址");
for(int i=0;i<con->size;i++)
{
printf("%3s %3s %3d %3s %3s\n",
con->a[i].name,
con->a[i].gender,
con->a[i].age,
con->a[i].tel,
con->a[i].addr
);
}
}
1.3.3Contact.c完整代码
#include "Contact.h"
#include "SeqList.h"
#include <string.h>
//通讯录的初始化
void ContactInit(Contact* con)
{
SLInit(con);
}
//通讯录的销毁
void ContactDesTroy(Contact* con)
{
SLDestroy(con);
}
//通讯录添加数据
void ContactAdd(Contact* con)
{
peoInfo info;
printf("请输入要添加的联系人姓名:\n");
scanf("%s",info.name);
printf("请输入要添加的联系人性别:\n");
scanf("%s",info.gender);
printf("请输入要添加的联系人年龄:\n");
scanf("%d",info.&age);
printf("请输入要添加的联系人的电话:\n");
scanf("%s",info.tel);
printf("请输入要添加的联系人的住址:\n");
scanf("%s",info.addr);
SLPushBack(con,info);
}
int FindByName(Contact *con,char name[])
{
for(int i=0;i<con->size;i++)
{
if(strcmp(con->a[i].name,name)==0)
return i;
}
return -1;
}
//通讯录删除数据
void ContactDel(Contact* con)
{
char name[NAME_MAX];
printf("请输入您要删除的联系人姓名:\n");
scanf("%s",name);
int find= FindByName(con,name);
if(find<0)
{
printf("您要删除的联系人不在通讯录内!\n");
return;
}
SLErase(con,find);
printf("删除成功!\n");
}
//通讯录的修改
void ContactModify(Contact* con)
{
printf("请输入您要修改的联系人姓名:\n");
char name[NAME_MAX];
scanf("%s",name);
int find= FindByName(con,name);
if(find<0)
{
printf("您要修改的联系人不存在!\n");
return;
}
printf("请输入新的姓名:");
scanf("%s",con->a[find].name);
printf("请输入新的性别:");
scanf("%s",con->a[find].gender);
printf("请输入新的年龄:");
scanf("%d",con->a[find].age);
printf("请输入新的电话:");
scanf("%s",con->a[find].tel);
printf("请输入新的住址:");
scanf("%s",con->a[find].addr);
printf("修改成功!\n");
}
//通讯录查找
void ContactFind(Contact* con)
{
char name[NAME_MAX];
printf("请输入您要查找的联系人姓名:\n");
scanf("%s",name);
int find= FindByName(con,name);
if(find<0)
{
printf("您要查找的联系人不在通讯录内!\n");
return;
}
printf("%s %s %s %s %s \n","姓名","性别","年龄","电话","地址");
printf("%3s %3s %3d %3s %3s\n",
con->a[find].name,
con->a[find].gender,
con->a[find].age,
con->a[find].tel,
con->a[find].addr
);
}
//展示通讯录数据
void ContactShow(Contact* con)
{
printf("%s %s %s %s %s \n","姓名","性别","年龄","电话","地址");
for(int i=0;i<con->size;i++)
{
printf("%3s %3s %3d %3s %3s\n",
con->a[i].name,
con->a[i].gender,
con->a[i].age,
con->a[i].tel,
con->a[i].addr
);
}
}
1.4通讯录的菜单设置
1.4.1 text.c
#include "SeqList.h"
void menu()
{
printf("**************通讯录*****************\n");
printf("******1.增加联系人 2.删除联系人******\n");
printf("******3.修改联系人 4.查找联系人******\n");
printf("******5.展示联系人 0. 退出 ******\n");
printf("************************************\n");
}
int main()
{
int select=-1;
Contact con;
ContactInit(&con);
do {
menu();
printf("请选择您的操作:\n");
scanf("%d",&select);
switch(select)
{
case 1:
ContactAdd(&con);
break;
case 2:
ContactDel(&con);
break;
case 3:
ContactModify(&con);
break;
case 4:
ContactFind(&con);
break;
case 5:
ContactShow(&con);
break;
case 0:
printf("退出通讯录\n");
break;
default:
printf("输入错误,请重新选择您的操作!\n");
break;
}
}while(select!=0);
ContactDesTroy(&con);
return 0;
}