目录
前言
一、基于动态顺序表实现通讯录
二、代码具体实现
2.1 初始化通讯录
2.2 添加通讯录数据
2.3 展示通讯录
2.4 按名字来查找通讯录信息
2.5 删除通讯录的数据
2.6 查找通讯录的数据
2.7 修改通讯录的数据
2.8 销毁通讯录
上传通讯录数据
写入通讯录数据
三、完整代码
总结
前言
之前我们讲了数据结构中的顺序表:数据结构——顺序表
今天我们基于顺序表来实现通讯录,实现添加,删除,查找,修改,展示的功能。通过结构体来存储通讯录的数据,通过菜单进行交互,最后进行上传到文件中保存,这就是我们通讯录的功能实现。
一、基于动态顺序表实现通讯录
以上就是通讯录的功能要求,现在我们就来实现代码。
二、代码具体实现
实现我们是基于顺序表代码实现的,所以我们需要顺序表的头文件
//Seqlist.h#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<string.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);
跟顺序表一样,只不过顺序表内容不是整型内容,而是我们定义的结构体内容(联系人信息)
//contact.h#define NAME_MAX 100
#define SEX_MAX 4
#define TEL_MAX 12
#define ADDR_MAX 100typedef struct PersonInfo
{char name[NAME_MAX];//姓名char sex[SEX_MAX];//性别int age;//年龄char tel[TEL_MAX];//电话char addr[ADDR_MAX];//住址
}PeoInfo;//结构体类型
现在我们就要进行通讯录的功能实现了
主要接口:
//contact.h//前置类型声明
struct Seqlist;//调用必须先声明typedef struct Seqlist contact;//给顺序表重命名为contact//初始化通讯录
void InitContact(contact* con);
//添加通讯录数据
void AddContact(contact* con);
//删除通讯录数据
void DelContact(contact* con);
//展⽰通讯录数据
void ShowContact(contact* con);
//查找通讯录数据
void FindContact(contact* con);
//修改通讯录数据
void ModifyContact(contact* con);
//销毁通讯录数据
void DestroyContact(contact* con);//读取本地通讯录
void LoadContact(contact* con);//上传通讯录数据到文件
void SaveContact(contact* con);
2.1 初始化通讯录
//初始化通讯录
void InitContact(contact* con) {SLInit(con);
}
调用顺序表的初始化函数SLInit函数,即可完成对通讯录的初始化。
2.2 添加通讯录数据
void AddContact(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);printf("添加成功\n");SLPushBack(con, info);//调用顺序表尾插
}
我们要添加联系人,就要添加一个我们定义的PeoInfo结构体(联系人信息)的结构体变量,然后往里面添加姓名,性别,年龄,电话,住址信息,最后插入通讯录。
2.3 展示通讯录
我们添加后查看通讯录里面的有哪些联系人信息。
void ShowContact(contact* con) {printf("%-10s %-4s %-4s %15s %-20s\n", "姓名", "性别", "年龄", "电话", "住址");for (int i = 0; i < con->size; i++) {//打印个数小于有效数据个数printf("%-10s %-4s %-4d %15s %-20s\n",con->arr[i].name, con->arr[i].sex,con->arr[i].age,con->arr[i].tel,con->arr[i].addr);}
}
2.4 按名字来查找通讯录信息
我们进行删除,修改,查找操作之前我们要找到操作的对象,我们以名字来查找。
int FindByName(contact* con, char name[]) {for (int i = 0; i < con->size; i++) {if (strcmp(con->arr[i].name, name) == 0) {return i;//找到返回下标}}return -1;//没找到返回-1
}
2.5 删除通讯录的数据
void DelContact(contact* con) {char name[NAME_MAX];//定义数组为删除人的名字printf("请输入删除人的姓名:\n");scanf("%s", name);int pos = FindByName(con, name);//进行查找if (pos < 0) {printf("没有找到删除的人名,删除失败\n");}else {SLErase(con, pos);printf("删除成功!\n");}}
我们调用顺序表删除任意位置的元素SLErase函数,进行删除通讯录里面的数据。
2.6 查找通讯录的数据
//查找通讯录的数据
void FindContact(contact* con) {char name[NAME_MAX];//定义数组为查找人的姓名printf("请输入查找人的姓名:\n");scanf("%s", name);int pos = FindByName(con, name);//查找是否存在if (pos < 0) {printf("没有找到,查找失败\n");}else {printf("找到了:\n");//找到了打印信息printf("%-10s %-4s %-4d %15s %-20s\n",con->arr[pos].name,con->arr[pos].sex,con->arr[pos].age,con->arr[pos].tel,con->arr[pos].addr);}
}
2.7 修改通讯录的数据
void ModifyContact(contact* con) {char name[NAME_MAX];//定义数组为修改人的姓名printf("请输入姓名:\n");scanf("%s", name);int pos = FindByName(con, name);//查找if (pos < 0) {printf("没有找到,修改失败\n");}else {printf("请输入修改人的姓名:\n");scanf("%s", &con->arr[pos].name);printf("请输入修改人的性别:\n");scanf("%s", &con->arr[pos].sex);printf("请输修改人的年龄:\n");scanf("%d", &con->arr[pos].age);printf("请输入修改人的电话:\n");scanf("%s", &con->arr[pos].tel);printf("请输入修改人的住址:\n");scanf("%s", &con->arr[pos].addr);printf("修改成功\n");}
}
2.8 销毁通讯录
//销毁通讯录数据
void DestroyContact(contact* con) {SLDestroy(con);
}
我们调用顺序表的销毁函数SLDestroy进行销毁通讯录的数据
但是我们要保留通讯录的数据,那么我们就可以在销毁前写入文件中:
上传通讯录数据
void SaveContact(contact* con) {FILE* pf = fopen("contact.txt", "wb");//文件指针if (pf == NULL) {perror("fopen error!\n");return;}//将通讯录数据写⼊⽂件for (int i = 0; i < con->size; i++){fwrite(con->arr + i, sizeof(PeoInfo), 1, pf);//通过fwrite写入文件}printf("通讯录数据保存成功!\n");
}
在下次使用时初始化中
写入通讯录数据
void LoadContact(contact* con) {FILE* pf = fopen("contact.txt", "rb");if (pf == NULL) {perror("fopen error!\n");return;}//循环读取⽂件数据PeoInfo info;//定义info为通讯录数据while (fread(&info, sizeof(PeoInfo), 1, pf))//读info类型数据不为空{SLPushBack(con, info);//尾插info数据}printf("历史数据导入通讯录成功!\n");
}
三、完整代码
通讯录功能头文件
//contact.h
#pragma once#define NAME_MAX 100
#define SEX_MAX 4
#define TEL_MAX 12
#define ADDR_MAX 100typedef struct PersonInfo
{char name[NAME_MAX];char sex[SEX_MAX];int age;char tel[TEL_MAX];char addr[ADDR_MAX];
}PeoInfo;//前置类型
struct Seqlist;typedef struct Seqlist contact;//初始化通讯录
void InitContact(contact* con);
//添加通讯录数据
void AddContact(contact* con);
//删除通讯录数据
void DelContact(contact* con);
//展⽰通讯录数据
void ShowContact(contact* con);
//查找通讯录数据
void FindContact(contact* con);
//修改通讯录数据
void ModifyContact(contact* con);
//销毁通讯录数据
void DestroyContact(contact* con);//读取本地通讯录
void LoadContact(contact* con);//上传通讯录数据到文件
void SaveContact(contact* con);
通讯录功能具体实现
//contact.c
#include"Seqlist.h"
#include"contact.h"//初始化通讯录
void InitContact(contact* con) {SLInit(con);LoadContact(con);
}
//添加通讯录数据
void AddContact(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);printf("添加成功\n");SLPushBack(con, info);
}
//展⽰通讯录
void ShowContact(contact* con) {printf("%-10s %-4s %-4s %15s %-20s\n", "姓名", "性别", "年龄", "电话", "住址");for (int i = 0; i < con->size; i++) {printf("%-10s %-4s %-4d %15s %-20s\n",con->arr[i].name, con->arr[i].sex,con->arr[i].age,con->arr[i].tel,con->arr[i].addr);}
}
//按名字来查找
int FindByName(contact* con, char name[]) {for (int i = 0; i < con->size; i++) {if (strcmp(con->arr[i].name, name) == 0) {return i;}}return -1;
}
//删除通讯录的数据
void DelContact(contact* con) {char name[NAME_MAX];printf("请输入删除人的姓名:\n");scanf("%s", name);int pos = FindByName(con, name);if (pos < 0) {printf("没有找到删除的人名,删除失败\n");}else {SLErase(con, pos);printf("删除成功!\n");}}
//查找通讯录的数据
void FindContact(contact* con) {char name[NAME_MAX];printf("请输入查找人的姓名:\n");scanf("%s", name);int pos = FindByName(con, name);if (pos < 0) {printf("没有找到,查找失败\n");}else {printf("找到了:\n");printf("%-10s %-4s %-4d %15s %-20s\n",con->arr[pos].name,con->arr[pos].sex,con->arr[pos].age,con->arr[pos].tel,con->arr[pos].addr);}
}
//修改通讯录数据
void ModifyContact(contact* con) {char name[NAME_MAX];printf("请输入姓名:\n");scanf("%s", name);int pos = FindByName(con, name);if (pos < 0) {printf("没有找到,修改失败\n");}else {printf("请输入修改人的姓名:\n");scanf("%s", &con->arr[pos].name);printf("请输入修改人的性别:\n");scanf("%s", &con->arr[pos].sex);printf("请输修改人的年龄:\n");scanf("%d", &con->arr[pos].age);printf("请输入修改人的电话:\n");scanf("%s", &con->arr[pos].tel);printf("请输入修改人的住址:\n");scanf("%s", &con->arr[pos].addr);printf("修改成功\n");}
}//销毁通讯录数据
void DestroyContact(contact* con) {SaveContact(con);SLDestroy(con);
}//读取本地通讯录
void LoadContact(contact* con) {FILE* pf = fopen("contact.txt", "rb");if (pf == NULL) {perror("fopen error!\n");return;}//循环读取⽂件数据PeoInfo info;while (fread(&info, sizeof(PeoInfo), 1, pf)){SLPushBack(con, info);}printf("历史数据导入通讯录成功!\n");
}//上传通讯录数据到文件
void SaveContact(contact* con) {FILE* pf = fopen("contact.txt", "wb");if (pf == NULL) {perror("fopen error!\n");return;}//将通讯录数据写⼊⽂件for (int i = 0; i < con->size; i++){fwrite(con->arr + i, sizeof(PeoInfo), 1, pf);}printf("通讯录数据保存成功!\n");
}
通讯录主函数
contactest.ccontactest.c
#define _CRT_SECURE_NO_WARNINGS 1
#include"contact.h"
#include"Seqlist.h"void num() {printf("*************************************\n");printf("**** 1. 添加联系人 2. 删除联系人****\n");printf("**** 3. 查找联系人 4. 修改联系人****\n");printf("**** 5. 展示通讯录 0. 退出 ****\n");printf("*************************************\n");
}int main() {int inputt = 0;contact con;InitContact(&con);do {num();printf("请输入操作:\n");scanf("%d", &inputt);switch (inputt){case 1:AddContact(&con);break;case 2:DelContact(&con);break;case 3: FindContact(&con);break;case 4:ModifyContact(&con);break;case 5:ShowContact(&con);break;case 0:printf("通讯录退出中--\n");break;}} while (inputt);DestroyContact(&con);return 0;
}
还要顺序表的代码,这里就不在赘述。
总结
上述文章讲了基于顺序表为主要框架来实现通讯录的功能,希望对你有所帮助。