一、功能要求
(1)⾄少能够存储100个⼈的通讯信息
(2)能够保存⽤⼾信息:名字、性别、年龄、电话、地址等
(3)增加联系⼈信息
(4)删除指定联系⼈
(5)查找制定联系⼈
(6)修改指定联系⼈
(7)显⽰联系⼈信息
二、代码实现
所需的头文件与源文件
SeqList.hSeqList.c //顺序表实现contact.hcontact.c //通讯录实现test.c //测试
SeqList.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include"contact.h"// 动态顺序表 -- 按需申请typedef PeoInfo SLDataType;
//动态顺序表
typedef struct SeqList
{SLDataType* arr;int size; // 有效数据个数int capacity; // 空间容量
}SL;//初始化
void SLInit(SL* ps);
//销毁
void SLDestroy(SL* ps);
//打印
void SLPrint(SL ps);
//扩容
void SLCheckCapacity(SL* ps);//头部插入 / 尾部插入
void SLPushFront(SL* ps, SLDataType x);
void SLPushBack(SL* ps, SLDataType x);
//头部插删除 / 尾部删除
void SLPopFront(SL* ps);
void SLPopBack(SL* ps);//指定位置之前插入/删除数据
void SLInsert(SL* ps, int pos, SLDataType x);
void SLErase(SL* ps, int pos);
int SLFind(SL* ps, SLDataType x);
SeqList.c
#include"SeqList.h"//初始化
void SLInit(SL* ps)
{ps->arr = NULL;ps->size = ps->capacity = 0;
}//销毁
void SLDestroy(SL* ps)
{if (ps->arr){free(ps->arr);}ps->arr = NULL;ps->size = ps->capacity = 0;
}//扩容
void SLCheckCapacity(SL* ps)
{if (ps->capacity == ps->size){//申请空间(增容用realloc)//要先判断capacity是否为零,如果为真默认给4个空间,如果为假直接乘2(三目操作符)int newCapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;SLDataType* tmp = ps->arr = (SLDataType*)realloc(ps->arr, newCapacity * sizeof(SLDataType));//要申请多大的空间if (tmp == NULL){perror("realloc fail!");exit(1);//直接推出程序,不在继续执行}//空间申请成功ps->arr = tmp;ps->capacity = newCapacity;}
}//尾插
void SLPushBack(SL* ps, SLDataType x)
{assert(ps);//等价于assert(ps != NULL)//插入数据之前要看空间够不够SLCheckCapacity(ps);//ps->arr[ps->size] = x;//++ps->size;ps->arr[ps->size++] = x;//可以一步到位也可以分两步写
}//头插
void SLPushFront(SL* ps, SLDataType x)
{assert(ps);SLCheckCapacity(ps);//先让顺序表中已有的数据整体往后挪动一位for (int i = ps->size; i > 0; i--){ps->arr[i] = ps->arr[i - 1];}ps->arr[0] = x;ps->size++;
}//打印
void SLPrint(SL ps)
{for (int i = 0; i < ps.size; i++){printf("%d ", ps.arr[i]);}printf("\n");
}//头删
void SLPopFront(SL* ps)
{assert(ps);assert(ps->size);//数据整体往前挪动一位for (int i = 0; i < ps->size - 1; i++){ps->arr[i] = ps->arr[i + 1];ps->size--;}
}//尾删
void SLPopBack(SL* ps)
{assert(ps);assert(ps->size);//顺序表不为空--ps->size;
}//在指定位置之前插入数据
void SLInsert(SL* ps, int pos, SLDataType x)
{assert(ps);assert(pos >= 0 && pos <= ps->size);//插入数据:空间够不够?SLCheckCapacity(ps);//让pos及以后的数据整体往后挪动一位for (int i = ps->size; i > pos; i--){ps->arr[i] = ps->arr[i - 1];//arr[pos+1] = arr[pos]}ps->arr[pos] = x;ps->size++;
}//删除指定位置的数据
void SLErase(SL* ps, int pos)
{assert(ps);assert(pos >= 0 && pos < ps->size);for (int i = pos; i < ps->size - 1; i++){ps->arr[i] = ps->arr[i + 1];}ps->size--;
}
contact.h
#pragma once
#define NAME_MAX 100
#define SEX_MAX 4
#define TEL_MAX 11
#define ADDR_MAX 100//前置声明typedef struct SeqList contact;//用户数据
//姓名 性别 年龄 电话 地址
typedef struct PersonInfo{char name[NAME_MAX];char sex[SEX_MAX];int age;char tel[TEL_MAX];char addr[ADDR_MAX];}PeoInfo;//初始化通讯录
void ContactInit(contact* con);//添加通讯录数据
void ContactAdd(contact* con);//删除通讯录数据
void ContactDel(contact* con);//展示通讯录数据
void ContactShow(contact* con);//查找通讯录数据
void ContactFind(contact* con);//修改通讯录数据
void ContactModify(contact* con);//销毁通讯录数据
void ContactDestroy(contact* con);
contact.c
#include"contact.h"
#include"SeqList.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.sex);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 (0 == strcmp(con->arr[i].name, name)){//找到了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 ContactShow(contact* con)
{//表头:姓名 性别 年龄 电话 地址printf("%s %s %s %s %s\n", "姓名", "性别", "年龄", "电话", "地址");//遍历通讯录,按照打印每个联系人数据for (int i = 0; i < con->size; i++){printf("%3s %2s %d %6s %s\n",con->arr[i].name,con->arr[i].sex,con->arr[i].age,con->arr[i].tel,con->arr[i].addr);}
}//修改通讯录数据
void ContactModify(contact* con)
{//要修改的联系人数据存在char name[NAME_MAX];printf("请输入要修改的用户姓名:\n");scanf("%s", name);int find = FindByName(con, name);if (find < 0){printf("要修改的联系人数据不存在\n");return;}//修改printf("请输入新的姓名\n");scanf("%s", con->arr[find].name);printf("请输入新的性别\n");scanf("%s", con->arr[find].sex);printf("请输入新的年龄\n");scanf("%d", &con->arr[find].age);printf("请输入新的电话\n");scanf("%s", con->arr[find].tel);printf("请输入新的地址\n");scanf("%s", con->arr[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 %2s %d %6s %s\n",con->arr[find].name,con->arr[find].sex,con->arr[find].age,con->arr[find].tel,con->arr[find].addr);
}
test.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 op = -1;contact con;ContactInit(&con);do {menu();printf("请输入您的操作:\n");scanf("%d", &op);//根据不同的选择执行不同的操作switch (op){case 1:ContactAdd(&con);break;case 2:ContactAdd(&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 (op != 0);ContactDestroy(&con);return 0;
}