前言
📚作者简介:爱编程的小马,正在学习C/C++,Linux及MySQL..
📚以后会将数据结构收录为一个系列,敬请期待
● 本期内容会给大家带来通讯录的讲解,主要是利用结构体来实现通讯录,该通讯录可以存储几百人甚至是几千人的信息,每个信息包括:姓名,年龄,性别,电话以及地址。准备好了就跟着小马出发吧。
通讯录
[2.1 通讯录的功能](#2.1 通讯录的功能)
[2.2 通讯录的定义](#2.2 通讯录的定义)
[2.3 录入人员信息的函数实现](#2.3 录入人员信息的函数实现)
[2.4 定义检查人员是否存在函数](#2.4 定义检查人员是否存在函数)
[2.5 删除通讯录中已经存在的信息函数实现](#2.5 删除通讯录中已经存在的信息函数实现)
[2.6 查找通讯录成员函数](#2.6 查找通讯录成员函数)
[2.7 修改通讯录成员函数](#2.7 修改通讯录成员函数)
[2.8 显示通讯录](#2.8 显示通讯录)
[2.9 给通讯录排序](#2.9 给通讯录排序)
[3.1 test.c](#3.1 test.c)
[3.2 contact.h](#3.2 contact.h)
[3.3 contact.c](#3.3 contact.c)
1. 通讯录环境及文件配置
本通讯录是在VS2019的环境下,需要创建三个文件,test.c ,contact.c ,contact.h
test.c //主函数,调用通讯录相关功能
contact.c //函数功能的实现
contact.h //函数头文件的包含及函数的声明
2. 通讯录的实现
2.1 通讯录的功能
2.2 通讯录的定义
首先需要一个菜单,可以提供给玩家选择:
c
void menu()
{
printf("******************************\n");
printf("**** 1.add 2.del ****\n");
printf("**** 3.search 4.modify ****\n");
printf("**** 5.show 6.sort ****\n");
printf("**** 0.exit ****\n");
printf("******************************\n");
}
通讯录的定义:
1、封装一个结构体信息用来存储人员信息
2、再需要一个结构体数组来管理这个人员信息(暂时能存储100个人)
c
#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 20
#define ADDR_MAX 30
#define ADD_ONCE 2
#define MAX 100
typedef struct peoinfo
{
char name[NAME_MAX];
int age;
char sex[SEX_MAX];
char tele[TELE_MAX];
char addr[ADDR_MAX];
}peoinfo;
typedef struct contact
{
peoinfo data [MAX];
int sz;
}contact;
2.3 录入人员信息的函数实现
1、判断:如果人员信息录入满了就不再录入了
2、挨个录入姓名,年龄,性别,电话以及住址,录入完成后打印增加成功,然后记录人员信息的sz往后走一步(sz++)
c
void AddContact(contact* pc)
{
assert(pc);
if (pc->sz == MAX)
{
printf("通讯录已满,请删除后重试\n");
return;
}
printf("请输入名字:>");
scanf("%s", pc->data[pc->sz].name);
printf("请输入年龄:>");
scanf("%d", &pc->data[pc->sz].age);
printf("请输入性别:>");
scanf("%s", pc->data[pc->sz].sex);
printf("请输入电话:>");
scanf("%s", pc->data[pc->sz].tele);
printf("请输入地址:>");
scanf("%s", pc->data[pc->sz].addr);
pc->sz++;
printf("添加成功\n");
}
2.4 定义检查人员是否存在函数
为什么要定义这个函数呢?因为两点原因:1、后面的删除,查找,修改人员信息是不是都要先确定这个人是否存在我们再进行下一步操作。2、在前面定义,后面直接引用即可,不用反复定义
c
int FindName(contact* pc,char name[])
{
int i = 0;
for (i = 0; i < pc->sz; i++)
{
if (strcmp(pc->data[i].name, name) == 0)
return i;
}
return -1;
}
2.5 删除通讯录中已经存在的信息函数实现
1、判断:如果通讯录为空,就不要删除了,直接返回
2、如果不为空,我们就调用检查人员是否存在这个函数,如果存在,则继续,如果不存在,就返回
3、如果有这个人,那应该从这个人的地址往后,依次向前覆盖,最后总数sz-1是不是就完成了删除
c
void DelContact(contact* pc)
{
char name[NAME_MAX];
printf("请输入要删除人的名字:>");
scanf("%s", name);
if (pc->sz == 0)
{
printf("通讯录为空,无法删除\n");
return;
}
int ret = FindName(pc, name);
if (ret == -1)
{
printf("查无此人,无法删除请重试\n");
return;
}
int i = 0;
for (i = ret; i < ret - 1; i++)
{
pc->data[i] = pc->data[i + 1];
}
pc->sz--;
printf("删除成功\n");
}
2.6 查找通讯录成员函数
1、判断:如果通讯录为空,不要查找了直接返回
2、调用检查人员存在函数,如果没有就直接返回,如果存在就直接打印人员信息
c
void SearchContact(contact* pc)
{
char name[NAME_MAX];
int i = 0;
printf("请输入被查找人的名字:>");
scanf("%s", name);
int ret = FindName(pc, name);
if (ret == -1)
{
printf("查无此人\n");
}
else
{
printf("%-20s%-5s%-5s%-12s%-20s\n", "姓名", "年龄", "性别", "电话", "地址");
printf("%-20s%-5d%-5s%-12s%-20s\n", pc->data[ret].name,
pc->data[ret].age,
pc->data[ret].sex,
pc->data[ret].tele,
pc->data[ret].addr);
}
}
2.7 修改通讯录成员函数
1、判断:如果通讯录为空就不要修改了,直接返回
2、调用检查人员存在函数,如果没有就直接返回,如果存在就直接修改人员信息
c
void ModifyContact(contact* pc)
{
char name[NAME_MAX];
int i = 0;
printf("请输入要修改人的名字:>");
scanf("%s", name);
int ret = FindName(pc, name);
if (ret == -1)
printf("要修改的人不存在\n");
else
{
printf("请输入名字:>");
scanf("%s", pc->data[ret].name);
printf("请输入年龄:>");
scanf("%d", &pc->data[ret].age);
printf("请输入性别:>");
scanf("%s", pc->data[ret].sex);
printf("请输入电话:>");
scanf("%s", pc->data[ret].tele);
printf("请输入地址:>");
scanf("%s", pc->data[ret].addr);
printf("修改成功\n");
}
}
2.8 显示通讯录
c
void ShowContact(contact* pc)
{
assert(pc);
if (pc->sz == 0)
printf("通讯录为空,无需打印\n");
else
{
int i = 0;
for (i = 0; i < pc->sz; i++)
{
printf("%-20s%-5s%-5s%-12s%-20s\n", "姓名", "年龄", "性别", "电话", "地址");
printf("%-20s%-5d%-5s%-12s%-20s\n", pc->data[i].name,
pc->data[i].age,
pc->data[i].sex,
pc->data[i].tele,
pc->data[i].addr);
}
}
}
2.9 给通讯录排序
1、首先需要确定按什么排序
2、实现的思想是使用qsort函数
c
void menun()
{
printf("******************************\n");
printf("**** 1.按名字 2.按年龄 ****\n");
printf("**** 3.按性别 4.按电话 ****\n");
printf("**** 5.按地址 ****\n");
printf("******************************\n");
}
int NAME(const void* p1, const void* p2)
{
return strcmp(((peoinfo*)p1)->name, ((peoinfo*)p2)->name);
}
int AGE(const void* p1, const void* p2)
{
return (((peoinfo*)p1)->age- ((peoinfo*)p2)->age);
}
int SEX(const void* p1, const void* p2)
{
return strcmp(((peoinfo*)p1)->sex, ((peoinfo*)p2)->sex);
}
int TELE(const void* p1, const void* p2)
{
return strcmp(((peoinfo*)p1)->tele, ((peoinfo*)p2)->tele);
}
int ADDR(const void* p1, const void* p2)
{
return strcmp(((peoinfo*)p1)->addr, ((peoinfo*)p2)->addr);
}
void SortContact(contact* pc)
{
menun();
int input = 0;
printf("请输入排序的方式:>");
scanf("%d", &input);
int (*cmp[6])(const void* p1, const void* p2) = { NULL,NAME,AGE,SEX,TELE,ADDR};
switch (input)
{
case 1:
qsort(pc->data, pc->sz, sizeof(peoinfo), cmp[input]);
break;
case 2:
qsort(pc->data, pc->sz, sizeof(peoinfo), cmp[input]);
break;
case 3:
qsort(pc->data, pc->sz, sizeof(peoinfo), cmp[input]);
break;
case 4:
qsort(pc->data, pc->sz, sizeof(peoinfo), cmp[input]);
break;
case 5:
qsort(pc->data, pc->sz, sizeof(peoinfo), cmp[input]);
break;
default:
printf("输入非法\n");
}
printf("排序成功\n");
}
3. 通讯录全部源码
3.1 test.c
c
#define _CRT_SECURE_NO_WARNINGS 1
#include "contact.h"
void menu()
{
printf("******************************\n");
printf("**** 1.add 2.del ****\n");
printf("**** 3.search 4.modify ****\n");
printf("**** 5.show 6.sort ****\n");
printf("**** 0.exit ****\n");
printf("******************************\n");
}
enum Option
{
EXIT,
ADD,
DEL,
SEARCH,
MODIFY,
SHOW,
SORT
};
int main()
{
int input = 0;
contact con;
Init(&con);
do
{
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case ADD:
AddContact(&con);
break;
case DEL:
DelContact(&con);
break;
case SEARCH:
SearchContact(&con);
break;
case MODIFY:
ModifyContact(&con);
break;
case SHOW:
ShowContact(&con);
break;
case SORT:
SortContact(&con);
break;
case EXIT:
{
printf("退出程序\n");
break;
}
default:
printf("非法输入,请重新输入\n");
}
} while (input);
return 0;
}
3.2 contact.h
c
#pragma once
#include<stdio.h>
#include<assert.h>
#include<string.h>
#include<stdlib.h>
#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 20
#define ADDR_MAX 30
#define ADD_ONCE 2
#define MAX 100
typedef struct peoinfo
{
char name[NAME_MAX];
int age;
char sex[SEX_MAX];
char tele[TELE_MAX];
char addr[ADDR_MAX];
}peoinfo;
typedef struct contact
{
peoinfo data [MAX];
int sz;
}contact;
void Init(contact * pc);
void AddContact(contact* pc);
void ShowContact(contact*pc);
void DelContact(contact* pc);
void SearchContact(contact *pc);
void ModifyContact(contact* pc);
void SortContact(contact* pc);
void free_contact(contact *pc);
3.3 contact.c
c
#define _CRT_SECURE_NO_WARNINGS 1
#include "contact.h"
void Init(contact* pc)
{
//静态版
assert(pc);
pc->sz = 0;
memset(pc->data, 0, sizeof(pc->data));
}
void AddContact(contact* pc)
{
assert(pc);
if (pc->sz == MAX)
{
printf("通讯录已满,请删除后重试\n");
return;
}
printf("请输入名字:>");
scanf("%s", pc->data[pc->sz].name);
printf("请输入年龄:>");
scanf("%d", &pc->data[pc->sz].age);
printf("请输入性别:>");
scanf("%s", pc->data[pc->sz].sex);
printf("请输入电话:>");
scanf("%s", pc->data[pc->sz].tele);
printf("请输入地址:>");
scanf("%s", pc->data[pc->sz].addr);
pc->sz++;
printf("添加成功\n");
}
void ShowContact(contact* pc)
{
assert(pc);
if (pc->sz == 0)
printf("通讯录为空,无需打印\n");
else
{
int i = 0;
for (i = 0; i < pc->sz; i++)
{
printf("%-20s%-5s%-5s%-12s%-20s\n", "姓名", "年龄", "性别", "电话", "地址");
printf("%-20s%-5d%-5s%-12s%-20s\n", pc->data[i].name,
pc->data[i].age,
pc->data[i].sex,
pc->data[i].tele,
pc->data[i].addr);
}
}
}
//从后往前覆盖就好了,总数删除完毕之后再减一个
int FindName(contact* pc,char name[])
{
int i = 0;
for (i = 0; i < pc->sz; i++)
{
if (strcmp(pc->data[i].name, name) == 0)
return i;
}
return -1;
}
void DelContact(contact* pc)
{
char name[NAME_MAX];
printf("请输入要删除人的名字:>");
scanf("%s", name);
if (pc->sz == 0)
{
printf("通讯录为空,无法删除\n");
return;
}
int ret = FindName(pc, name);
if (ret == -1)
{
printf("查无此人,无法删除请重试\n");
return;
}
int i = 0;
for (i = ret; i < ret - 1; i++)
{
pc->data[i] = pc->data[i + 1];
}
pc->sz--;
printf("删除成功\n");
}
void SearchContact(contact* pc)
{
char name[NAME_MAX];
int i = 0;
printf("请输入被查找人的名字:>");
scanf("%s", name);
int ret = FindName(pc, name);
if (ret == -1)
{
printf("查无此人\n");
}
else
{
printf("%-20s%-5s%-5s%-12s%-20s\n", "姓名", "年龄", "性别", "电话", "地址");
printf("%-20s%-5d%-5s%-12s%-20s\n", pc->data[ret].name,
pc->data[ret].age,
pc->data[ret].sex,
pc->data[ret].tele,
pc->data[ret].addr);
}
}
void ModifyContact(contact* pc)
{
char name[NAME_MAX];
int i = 0;
printf("请输入要修改人的名字:>");
scanf("%s", name);
int ret = FindName(pc, name);
if (ret == -1)
printf("要修改的人不存在\n");
else
{
printf("请输入名字:>");
scanf("%s", pc->data[ret].name);
printf("请输入年龄:>");
scanf("%d", &pc->data[ret].age);
printf("请输入性别:>");
scanf("%s", pc->data[ret].sex);
printf("请输入电话:>");
scanf("%s", pc->data[ret].tele);
printf("请输入地址:>");
scanf("%s", pc->data[ret].addr);
printf("修改成功\n");
}
}
void menun()
{
printf("******************************\n");
printf("**** 1.按名字 2.按年龄 ****\n");
printf("**** 3.按性别 4.按电话 ****\n");
printf("**** 5.按地址 ****\n");
printf("******************************\n");
}
int NAME(const void* p1, const void* p2)
{
return strcmp(((peoinfo*)p1)->name, ((peoinfo*)p2)->name);
}
int AGE(const void* p1, const void* p2)
{
return (((peoinfo*)p1)->age- ((peoinfo*)p2)->age);
}
int SEX(const void* p1, const void* p2)
{
return strcmp(((peoinfo*)p1)->sex, ((peoinfo*)p2)->sex);
}
int TELE(const void* p1, const void* p2)
{
return strcmp(((peoinfo*)p1)->tele, ((peoinfo*)p2)->tele);
}
int ADDR(const void* p1, const void* p2)
{
return strcmp(((peoinfo*)p1)->addr, ((peoinfo*)p2)->addr);
}
void SortContact(contact* pc)
{
menun();
int input = 0;
printf("请输入排序的方式:>");
scanf("%d", &input);
int (*cmp[6])(const void* p1, const void* p2) = { NULL,NAME,AGE,SEX,TELE,ADDR};
switch (input)
{
case 1:
qsort(pc->data, pc->sz, sizeof(peoinfo), cmp[input]);
break;
case 2:
qsort(pc->data, pc->sz, sizeof(peoinfo), cmp[input]);
break;
case 3:
qsort(pc->data, pc->sz, sizeof(peoinfo), cmp[input]);
break;
case 4:
qsort(pc->data, pc->sz, sizeof(peoinfo), cmp[input]);
break;
case 5:
qsort(pc->data, pc->sz, sizeof(peoinfo), cmp[input]);
break;
default:
printf("输入非法\n");
}
printf("排序成功\n");
}
总结
上文就是通讯录的详细讲解和全部源码,下一节会给大家更新动态内存存储相关的知识。
如果这份博客对大家有帮助,希望各位给小马一个大大的点赞鼓励一下,如果喜欢,请收藏一下,谢谢大家!!!
制作不易,如果大家有什么疑问或给小马的意见,欢迎评论区留言。