本文通过顺序表实现通讯录的功能,增删查改数据
首先实现顺序表的功能,再用顺序表实现通讯录的功能
顺序表中的成员为一个结构体对象con,自定义的类型,里面包含着联系人的姓名性别年龄电话地址
seqlist.h:顺序表头文件
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<assert.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"contact.h"//通讯录功能头文件,后面会加入
typedef con type;
typedef struct Seqlist {
type* data;//顺序表存储的数据类型,此处为con,后续定义的结构体类型
int size;//当前数据个数
int capacity;//数据总容量
}sl;
//初始化顺序表
void initialize(sl* ps);
//销毁线性表
void destory(sl* ps);
//判断是否满员;
void isfull(sl* ps);
//头插数据
void headinsert(sl* ps,type c);
//尾插数据
void tailinsert(sl* ps,type c);
//头删数据
void headdelete(sl* ps);
//尾删数据
void taildelete(sl* ps);
//删除指定数据
void delete(sl* ps,int p);
seqlist.c:顺序表功能实现文件
#include"seqlist.h"
void initialize(sl* ps){//初始化顺序表
ps->data = NULL;
ps->size = ps->capacity = 0;
}
void destory(sl* ps) {//销毁顺序表
if (ps->data) {
free(ps->data);
ps->data = NULL;
}
ps->size = ps->capacity = 0;
}
void isfull(sl* ps) {//判断顺序表是否满员,满了则扩容为原来容量的两倍
assert(ps);//ps不能为野指针
if (ps->size == ps->capacity) {//如果当前数量达到容量
int newcapacity =ps->capacity== 0 ? 4 : 2 * ps->capacity;//未创建初始容量则是4,创建了则是扩容到当前容量的两倍
type* p = (type*)realloc(ps->data, newcapacity * sizeof(type));//开辟空间
if (p == NULL) {//开辟失败则退出
perror("申请失败");
return;
}
ps->data = p;//开辟空间成功则指针重新赋值保证有效;
ps->capacity = newcapacity;//当前容量扩充成功
}
}
void headinsert(sl* ps,type c) {//头插法
assert(ps);//避免指针为空
isfull(ps);//判断是否容量已满,满了则扩容
for (int i = ps->size; i>=1; i--) {
ps->data[i] = ps->data[i-1];
}
ps->data[0] = c;
ps->size++;}
void tailinsert(sl* ps,type c) {//尾插法
assert(ps);
ps->data[ps->size++] = c;
}
void headdelete(sl* ps){//头删法
if (ps->data) {
for (int i = 0; i<=ps->size-2; i++) {
ps->data[i] = ps->data[i + 1];
}
ps->size--;
}
}
void taildelete(sl* ps){//尾删法
assert(ps);
ps->size--;}
void delete(sl* ps,int p) {//删除指定位置数据
assert(ps);
assert(ps->size >= 0 && ps->size <= ps->capacity);//保证指针访问有效位置
for (int i = p; i<=ps->size-2; i++) {
ps->data[i] = ps->data[i + 1];
}
ps->size--;
return;
}
顺序表功能已经实现完成,接下来实现通讯录功能,通讯录实质说顺序表,不同的名字,功能实质上和顺序表差不多,有细微差别
contact.h:通讯录头文件
#pragma once
#define name_max 20
#define gender_max 20
#define tel_max 20
#define add_max 20
typedef struct person {
char name[name_max];//名字
char gender[gender_max];//性别
int age;//年龄
char tel[tel_max];//电话
char address[add_max];//地址
}con;//定义的con结构体类型
typedef struct Seqlist contact;//前置申明,contact就是seqlist顺序表,不同名字而已
//通讯录初始化
void contactinit(contact* p);
//通讯录增加联系人
void contactadd(contact* p);
//删除联系人
int find(const contact* p,char*s);
void contactdel(contact* p);
//查找联系人
void contactsea(const contact*p);
//展示通讯录
void contactshow(contact p);
//更改通讯录
void contactmodify(contact* p);//删除通讯录
void contactdestroy(contact* p);
contact.c:通讯录实现代码
#include"seqlist.h"
//通讯录初始化void contactinit(contact* p) {
initialize(p);//顺序表初始化
}
//通讯录增加联系人
void contactadd(contact* p) {
assert(p);//避免野指针
isfull(p);//判断数据是否满员,满了则扩容为两倍
con f;//创建临时结构体用于存储接下来要输入的联系人信息
printf("请输入要增加联系人姓名\n");
scanf("%s", f.name);
printf("请输入要增加联系人性别\n");
scanf("%s", f.gender);
printf("请输入要增加联系年龄\n");
scanf("%d", &f.age);
printf("请输入要增加联系人电话\n");
scanf("%s", f.tel);
printf("请输入要增加联系人地址\n");
scanf("%s", f.address);
headinsert(p, f);//我这里选择的是头插法增添数据
printf("添加联系人成功!\n");
}
//查找联系人函数,查找成功返回该联系人下标
int find(const contact *p,char*s) {
for (int i = 0; i < p->size; i++) {//遍历结构体成员data数组
if (strcmp(p->data[i].name, s) == 0)return i;//找到则返回该联系人数组下标}
return -1;//没找到则返回-1
}
void contactsea(const contact* p){//查找联系人
char name[name_max];//存储接下来要输入的待查找人姓名
printf("请输入你要查找的联系人姓名\n");
scanf("%s", name);
int ret = find(p, name);//增添ret变量存储查找函数得到的联系人数组下标
if (ret >= 0) {//如果找到则打印该联系人
printf("联系人姓名%s\t 联系人性别%s\t 联系人年龄%d\t ;联系人电话%s\t 联系人地址%s\t\n", p->data[ret].name, p->data[ret].gender, p->data[ret].age,p->data[ret].tel,p->data[ret].address);
return;
}
else {
printf("未找到该联系人\n");
return;
}}
//删除联系人
void contactdel(contact* p) {
char name[name_max];
printf("请输入你要删除联系人的姓名\n");
scanf("%s", name);
int ret = find(p,name);//先找到要删除的联系人数组下标
if (ret >= 0) {
delete(p, ret);//顺序表删除指定位置元素
printf("删除成功!\n");
return;
}
else {
printf("未找到该联系人\n");
return;
}
}
//展示通讯录
void contactshow(contact p) {//遍历整个通讯录
for (int i = 0; i < p.size; i++) {
printf("联系人姓名%s\t 联系人性别%s\t 联系人年龄%d\t ;联系人电话%s\t 联系人地址%s\t\n", p.data[i].name, p.data[i].gender, p.data[i].age, p.data[i].tel, p.data[i].address);
}
return;
}
//修改联系人
void contactmodify(contact* p) {
char s[20] = { 0 };
printf("请输入要修改的联系人姓名\n");
scanf("%s", s);
int ret = find(p, s);
if (ret >= 0) {
printf("请输入要修改后联系人姓名\n");
scanf("%s", p->data[ret].name);
printf("请输入要修改后联系人性别\n");
scanf("%s", p->data[ret].gender);
printf("请输入要修改后联系人年龄\n");
scanf("%d", &p->data[ret].age);
printf("请输入要修改后联系人电话\n");
scanf("%s", p->data[ret].tel);
printf("请输入要修改后联系人地址\n");
scanf("%s", p->data[ret].address);
printf("修改成功!\n");
}
else printf("没有改联系人");
return;
}
void contactdestroy(contact* p) {//销毁通讯录
destory(p);
}
通讯录功能已经全部实现,接下来测试并图形化页面
#include"seqlist.h"
void x() {
printf("****************通讯录**********************\n");
printf("***1添加联系人****************2删除联系人***\n");
printf("***3查找联系人****************4更改联系人***\n");
printf("***5展示联系人****************0退出*********\n");
printf("********************************************\n");
return;
}
int main() {
contact p;//创建通讯录
contactinit(&p);//通讯录初始化
int a = -1;
do {
x();//打印菜单
if (scanf("%d", &a) == 1) {//如果输入为1个整数switch (a)
{
case 1:
contactadd(&p);//添加联系人
break;
case 2:
contactdel(&p);//删除联系人
break;
case 3:
contactsea(&p);//查找联系人
break;
case 4:
contactmodify(&p);//修改联系人
break;
case 5:
contactshow(p);//展示通讯录
break;
case 0://退出
return 0;
break;
default://
printf("输入错误,请重新输入!\n");
break;
}
}
else {//输入非整数的情况,如标点符号
printf("请输入整数\n");
while(getchar()!='\n');//输入非整数的情况,如标点符号,则情况缓冲区的字符
continue;//跳过本次循环
}}
while (a!=0);contactdestroy(&p);
return 0;
}
简单测试一下,都可以运行