文章目录
- 概述
- [1. 通讯录的效果](#1. 通讯录的效果)
- [2. SeqList.h](#2. SeqList.h)
- [3. Contact.h](#3. Contact.h)
- [4. SeqList.c](#4. SeqList.c)
- [5. Contact.c](#5. Contact.c)
- [6. test.c](#6. test.c)
概述
通讯录项目是基于顺序表这个数据结构来实现的。如果说数组是苍蝇小馆,顺序表是米其林的话,那么通讯录就是国宴。
换句话说,通讯录就是顺序表中存储结构体数据的。
那我在这里就给出所有的代码,具体细节这里就不再多说了,代码中都有注释。需要的可以自己复制粘贴。
1. 通讯录的效果
至于功能6大家可以执行测试。
下面,我将分文件展示每个文件的所有代码,有需要的读者可以自行的拷贝。
2. SeqList.h
c
#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 SLPrint(SL s);
//顺序表的初始化
void SLInit(SL* ps);
//顺序表的销毁
void SLDestory(SL* ps);
//尾插
void SLPushBack(SL* ps, SLDataType x);
//头插
void SLPushFront(SL* ps, SLDataType x);
//尾删
void SLPopBack(SL* ps);
//头删
void SLPopFront(SL* ps);
//指定位置之前插入数据
void SLInsert(SL* ps, int pos, SLDataType x);
//删除指定位置的数据
void SLErase(SL* ps ,int pos);
//找到指定位置的数据
int SLFind(SL* ps, SLDataType x);
3. Contact.h
c
#include<string.h>
typedef struct PersonInfo
{
char name[NAME_MAX]; //姓名
char gender[GENDER_MAX]; //性别
int age; //年龄
char tel[TEL_MAX]; //电话
char addr[ADDR_MAX]; //住址
}PeoInfo;
//核心:要用到顺序表的相关的方法,对通讯录的操作实际上就是对顺序表的操作
// 为了方便后面的操作,我们给顺序表起个别名为contact
//前置声明
//typedef SL contact;//这样写看似没有什么问题,但是你并编译之后就会发现一堆的报错
//原因在于,此操作为前置声明,就是在还未定义该结构之前,但是我要提前使用该声明就可以使用。
//适用场景为:多文件编写,头文件之间包含关系。
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 SaveContact(contact* con);
4. SeqList.c
c
#define _CRT_SECURE_NO_WARNINGS
#include"SeqList.h"
void SLInit(SL* ps)
{
ps->arr = NULL;
ps->size = ps->capacity = 0;
}
void SLDestory(SL* ps)
{
if (ps->arr) //相当于ps->arr != NULL
{
free(ps->arr);
}
ps->arr = NULL;
ps->size = ps->capacity = 0;
}
//void SLPrint(SL s)
//{
// int i = 0;
// for (i = 0; i < s.size; i++)
// {
// printf("%d ",s.arr[i]);
// }
// printf("\n");
//}
void SLCheckCapacity(SL* ps)
{
if (ps->capacity == ps->size)
{
//空间不够用,扩容
SL* tmp = NULL;
int newscapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
tmp = (SL*)realloc(ps->arr, newscapacity * sizeof(SLDataType));
if (tmp == NULL)
{
perror("realloc fail");
exit(EXIT_FAILURE);
}
//扩容成功
ps->arr = tmp;
ps->capacity = newscapacity;
}
}
void SLPushBack(SL* ps, SLDataType x)
{
assert(ps);
//在这之前得先判断,可用空间与有效数据个数之间的关系
SLCheckCapacity(ps);
ps->arr[ps->size++] = x;
}
void SLPushFront(SL* ps, SLDataType x)
{
assert(ps);
SLCheckCapacity(ps);
//第一步:要把所有的数据都往后挪动一位
int i = 0;
for (i = ps->size; i > 0; i--)
{
ps->arr[i] = ps->arr[i - 1];
}
//第二步:将数据插入到头部
ps->arr[0] = x;
//第三步:更新有效数据的个数
ps->size++;
}
void SLPopBack(SL* ps)
{
assert(ps);
assert(ps -> arr);
//这里通过ps->size的关系就可以直接控制,不再访问这个数据,也就是删除了
ps->size--;
}
void SLPopFront(SL* ps)
{
assert(ps);
assert(ps->arr);
int i = 0;
//用后一个数据覆盖前一个数据,从第一个数据开始
for (i = 0; i < ps->size-1; i++)
{
ps->arr[i] = ps->arr[i + 1];
}
//更新有效数据个数
ps->size--;
}
void SLInsert(SL* ps, int pos, SLDataType x)
{
assert(ps);
SLCheckCapacity(ps);
int i = 0;
for (i = ps->size; i > pos; i--)
{
ps->arr[i] = ps->arr[i - 1];
}
ps->arr[pos] = x;
ps->size++;
}
void SLErase(SL* ps, int pos)
{
assert(ps);
assert(ps->arr);
int i = 0;
for (i = pos; i < ps->size - 1; i++)
{
ps->arr[i] = ps->arr[i + 1];
}
ps->size--;
}
5. Contact.c
c
#define _CRT_SECURE_NO_WARNINGS
#include"SeqList.h"
#include"Contact.h"
void InitContact(contact* con)
{
SLInit(con);
}
void AddContact(contact* con) //尾插
{
assert(con);
PeoInfo pefo;
printf("请输入姓名:\n");
scanf("%s",pefo.name);
printf("请输入性别:\n");
scanf("%s", pefo.gender);
printf("请输入年龄:\n");
scanf("%d", &pefo.age);
printf("请输入电话:\n");
scanf("%s", pefo.tel);
printf("请输入住址:\n");
scanf("%s", pefo.addr);
//复用顺序表的方法
SLPushBack(con,pefo);
printf("数据已经成功添加!\n");
}
int Find(contact* con,PeoInfo pefo)
{
int i = 0;
for (i = 0; i < con->size; i++)
{
if (!strcmp(con->arr[i].tel, pefo.tel))
{
return i;
}
}
return -1;
}
void DelContact(contact* con)
{
assert(con);
PeoInfo pefo;
printf("请输入想要删除联系人的电话:\n");
scanf("%s",pefo.tel);
int find = Find(con, pefo);
if (find < 0)
{
//没有找到
printf("要删除的数据已经不存在\n");
return;
}
//找到了
SLErase(con,find);
printf("数据已经删除\n");
}
void ShowContact(contact* con)
{
printf("姓名\t性别\t年龄\t电话\t住址\n");
for (int i = 0; i < con->size; i++)
{
printf("%s\t", con->arr[i].name); //姓名
printf("%s\t", con->arr[i].gender); //性别
printf("%d\t", con->arr[i].age); //年龄
printf("%s\t", con->arr[i].tel); //电话
printf("%s\t", con->arr[i].addr); //住址
printf("\n");
}
}
void FindContact(contact* con)
{
PeoInfo pefo;
printf("请输入要查找通讯人的电话:\n");
scanf("%s",pefo.tel);
int find = Find(con, pefo);
if (find < 0)
{
printf("要查找的联系人数据不存在\n");
return;
}
//找到了
printf("姓名\t性别\t年龄\t电话\t住址\n");
printf("%s\t", con->arr[find].name); //姓名
printf("%s\t", con->arr[find].gender); //性别
printf("%d\t", con->arr[find].age); //年龄
printf("%s\t", con->arr[find].tel); //电话
printf("%s\t", con->arr[find].addr); //住址
printf("\n");
}
void ModifyContact(contact* con)
{
assert(con);
PeoInfo pefo;
printf("请输入要修改联系人的姓名:\n");
scanf("%s",pefo.name);
int i = 0;
for (i = 0; i < con->size; i++)
{
if (!strcmp(con->arr[i].name, pefo.name))
{
//匹配
printf("请输入姓名:\n");
scanf("%s", con->arr[i].name);
printf("请输入性别:\n");
scanf("%s", con->arr[i].gender);
printf("请输入年龄:\n");
scanf("%d", &con->arr[i].age);
printf("请输入电话:\n");
scanf("%s", con->arr[i].tel);
printf("请输入住址:\n");
scanf("%s", con->arr[i].addr);
break;
}
}
if (i == con->size)
{
printf("被修改的数据不存在\n");
}
}
void DestroyContact(contact* con)
{
assert(con);
SLDestory(&con);
}
void SaveContact(contact* con)
{
assert(con);
int i = 0;
//打开文件
FILE* fp = fopen("contact.txt","w");
if (fp == NULL)
{
perror("fopen fail");
exit(1);
}
//写文件
fprintf(fp,"姓名\t性别\t年龄\t电话\t住址\n");
for (i = 0; i < con->size; i++)
{
fprintf(fp,"%s\t%s\t%d\t%s\t%s\n",
con->arr[i].name,
con->arr[i].gender,
con->arr[i].age,
con->arr[i].tel,
con->arr[i].addr );
}
printf("数据已经安全存储\n");
//关闭文件
fclose(fp);
fp = NULL;
}
6. test.c
c
#include"SeqList.h"
void meun()
{
printf("*********************************************\n");
printf("**************** 通讯录 *****************\n");
printf("******* 1.添加联系人 2.删除联系人 *********\n");
printf("******* 3.修改联系人 4.查找联系人 *********\n");
printf("******* 5.展示通讯录 6.保存数据 *********\n");
printf("******* 0.退出 *********\n");
printf("*********************************************\n");
}
int main()
{
int input = 0;
contact con;
InitContact(&con);
do
{
meun();
printf("请输入你的操作:\n");
scanf("%d", &input);
switch (input)
{
case 1:
AddContact(&con);
break;
case 2:
DelContact(&con);
break;
case 3:
ModifyContact(&con);
break;
case 4:
FindContact(&con);
break;
case 5:
ShowContact(&con);
break;
case 6:
SaveContact(&con);
break;
case 0:
printf("程序已安全退出!\n");
break;
default:
printf("输入错误,请重新输入\n");
break;
}
} while (input);
return 0;
}
以上就是本次通讯录的全部代码了,如果又不理解的地方,可以在评论区提问。
最后,觉得本文写的不错的话,别忘了给偶点赞哦!