目录
一.前言
二.准备工作
三.ContactTest.c测试区
1.菜单
2.选择功能
四.Contact.h头文件引用区
1.通讯录成员结构体函数的创建
2.实现功能函数的创建
五.ContactRealize.c功能实现区
1.初始化成员信息
2.查找目标成员位置
3.增加联系人
4.删除指定联系人
5.查找指定联系人
6.修改指定联系人
7.浏览所有联系人
8.清空所有联系人
9.排序所有联系人
六.源码
1.ContactTest.c源码
2.Contact.h源码
3.ContactRealize.c源码
一.前言
本文讲通过c语言实现通讯录的功能,具体功能为1.添加、2.删除、3.查找、4.修改、5.浏览、6.清空、7.排序以及最后的0.退出通讯录功能。
二.准备工作
区域化编辑:
实现简单的通讯录可以分配为三大块,第一块为测试区,第二块为头文件引用区,第三块最重要,为调用实现通讯录功能函数的实现区块,我们将其分别命名为ContactTest.c,Contact.h和ContactRealize.c。
三.ContactTest.c测试区
1.菜单
以使用者的角度来看,需要了解到有哪些功能,那么我们就需要提供一个简洁明了的菜单功能,以便使用者使用相应的功能,参考菜单可如下:
void menu()
{
printf("*******************************\n");
printf("****** 通讯录 ******\n");
printf("****** 1.添加 2.删除 ******\n");
printf("****** 3.查找 4.修改 ******\n");
printf("****** 5.阅览 6.清空 ******\n");
printf("****** 7.排序 0.退出 ******\n");
printf("*******************************\n");
}
效果如下:
2.选择功能
这里我们使用switch函数来实现功能的选择,又因为会有重复的使用,因此可以使用do_while函数来实现循环,主函数我们可以这样设计:
int main()
{
int s;
Contact con;
InitContact(&con);
do
{
menu();
scanf("%d", &s);
switch (s)
{
case 1:
AddContact(&con);
break;
case 2:
DelContact(&con);
break;
case 3:
SearchContact(&con);
break;
case 4:
ModifyContact(&con);
break;
case 5:
ReadContact(&con);
break;
case 6:
EmptyContact(&con);
break;
case 7:
SortContact(&con);
break;
case 0:
printf("已成功退出!\n");
break;
default:
printf("请输入正确的选项!\n");
}
} while (s);
return 0;
}
此时我们就已经将退出的功能完成啦!而这里各个函数的调用以及结构体的创建还没有实现,我们将在后文详细说明。
四.Contact.h头文件引用区
1.通讯录成员结构体函数的创建
每个通讯录成员都有着一定的信息,又相互关联,使用结构体保存这一系列数据相对要方便很多;而通讯录成员并不是一个,所以我们需要一个结构体数组,同时还要了解到当前通讯录成员的数量,以此来实现通讯录的各项功能,具体结构体实现如下:
#define MAX 1000
#define NAME_MAX 20
#define SEX_MAX 5
#define ADDR_MAX 30
#define TELE_MAX 12
//个体成员信息
typedef struct ContactMember
{
char Name[NAME_MAX];
char Sex[SEX_MAX];
int Age;
char Number[TELE_MAX];
char Address[ADDR_MAX];
}ContactMember;
//所有成员信息
typedef struct Contact
{
ContactMember ContactMembers[MAX];
int sz;
}Contact;
这里定义各个成员信息具体内容的大小是为了方便修改,以达到简洁方便的目的。
2.实现功能函数的创建
因为要用到具体通讯录成员的信息和当前成员数量的信息,我们可以把Contact*类型的函数传递进功能函数,具体函数如下:
//初始化通讯录
void InitContact(Contact* con);
//增加联系人
void AddContact(Contact* con);
//删除指定联系人
void DelContact(Contact* con);
//查找指定联系人
void SearchContact(Contact* con);
//修改指定联系人
void ModifyContact(Contact* con);
//查看所有联系人
void ReadContact(Contact* con);
//清空所有联系人
void EmptyContact(Contact* con);
//排序所有联系人
void SortContact(Contact* con);
设置返回值为空,因为不需要返回值,只要实现相应功能就行了;同时,传递结构体指针是为了提高内存的性能,如果使用的Contact类型的函数,那么将又要为结构体数组开辟出一大块空间来实现函数,大量挤占内存,不是明智之举。
五.ContactRealize.c功能实现区
1.初始化成员信息
因为创建的Contact函数并没有初始化,因此先将其初始化将是一份安全保险,养成良好习惯,从你我做起。
//初始化成员信息
void InitContact(Contact* con)
{
con->sz = 0;//初始化下标
memset(con, 0, sizeof(con));//初始化所有成员
}
这里成员数量还是好初始化的,而成员结构体数组可以用memset函数来帮助我们实现初始化。
2.查找目标成员位置
具体功能中虽然没有该函数的使用,但该函数频繁出现在部分功能函数实现的内容中,在此单独写出来可以防止码重复代码,节约时间成本。
//查找目标成员位置
int FindName(Contact* con, char* name)
{
for (int i = 0; i < con->sz; i++)
{
if (strcmp(con->ContactMembers[i].Name, name) == 0)
{
return i;
}
}
return -1;
}
这里我们使用姓名来查找目标成员,将目标成员的姓名通过遍历和strcmp函数与各个成员信息比对从来找到目标成员的下标(位置)。
3.增加联系人
增加成员,需要将姓名、性别等信息录入相应位置的结构体,同时sz可以充当当前位置和数量的值,添加成功后联系人成员+1,但要防止超出存储上限的情况,可以在添加联系人之前做出判断来防止此类情况的发生。
//增加联系人
void AddContact(Contact* con)
{
assert(con);
if (con->sz == MAX)
{
printf("通讯录已满!\n");
return;
}
//增加
printf("请输入姓名:");
scanf("%s", con->ContactMembers[con->sz].Name);
printf("请输入性别:");
scanf("%s", con->ContactMembers[con->sz].Sex);
printf("请输入年龄:");
scanf("%d", &con->ContactMembers[con->sz].Age);
printf("请输入住址:");
scanf("%s", con->ContactMembers[con->sz].Address);
printf("请输入号码:");
scanf("%s", con->ContactMembers[con->sz].Number);
printf("输入完毕!\n");
con->sz++;
}
效果如下:
4.删除指定联系人
删除目标成员,首先就要先找到目标成员,此时先前写到的查找目标函数就可以直接调用啦!我们可以调用memmove来实现函数的删除,将删除目标的后面的成员全都向前移动一位,将目标成员的信息覆盖掉,便可以达到删除的效果啦!同时,还要小心没有可以删除目标的情况,在删除前先判断排除该情况。
//删除指定联系人
void DelContact(Contact* con)
{
assert(con);
if (con->sz == 0)
{
printf("没有可以删除的目标!\n");
return;
}
//查找
printf("请输入目标删除人:");
char name[NAME_MAX];
scanf("%s", name);
int ret = FindName(con, name);
if (ret == -1)
{
printf("目标人物不存在!\n");
return;
}
//删除
memmove(con->ContactMembers + ret, con->ContactMembers + ret + 1, sizeof(con->ContactMembers[0]) * (con->sz - ret - 1));
printf("删除成功!\n");
con->sz--;
}
5.查找指定联系人
此处又用到了查找目标联系人的函数,直接调用后打印即可。
//查找指定联系人
void SearchContact(Contact* con)
{
assert(con);
//查找
char name[NAME_MAX];
printf("请输入要查询的人:");
scanf("%s", name);
int ret = FindName(con, name);
if (ret == -1)
{
printf("查询目标不存在!\n");
return;
}
//显示
printf("%-20s\t%-5s\t%s\t%-30s\t%-12s\n", "姓名", "性别", "年龄", "地址", "号码");
printf("%-20s\t%-5s\t%d\t%-30s\t%-12s\n", con->ContactMembers[ret].Name,
con->ContactMembers[ret].Sex,
con->ContactMembers[ret].Age,
con->ContactMembers[ret].Address,
con->ContactMembers[ret].Number);
}
值得注意的是直接打印出来未免太过生硬,所以这里添加了姓名等标签在上一行来标志清楚,同时采用左对齐的方式,清晰美观。模拟实现如下:
6.修改指定联系人
这个函数于查找函数有着异曲同工之妙,只需要将打印目标成员信息的步骤改为输入即可。
//修改指定联系人
void ModifyContact(Contact* con)
{
assert(con);
//查找
char name[NAME_MAX];
printf("请输入要修改目标的姓名:");
scanf("%s", name);
int ret = FindName(con, name);
if (ret == -1)
{
printf("修改目标不存在!\n");
return;
}
//修改
printf("请输入要修改的姓名:");
scanf("%s", con->ContactMembers[ret].Name);
printf("请输入要修改的性别:");
scanf("%s", con->ContactMembers[ret].Sex);
printf("请输入要修改的年龄:");
scanf("%d", &con->ContactMembers[ret].Age);
printf("请输入要修改的地址:");
scanf("%s", con->ContactMembers[ret].Address);
printf("请输入要修改的号码:");
scanf("%s", con->ContactMembers[ret].Number);
printf("修改完毕!\n");
}
效果如下:
7.浏览所有联系人
该函数也类似于查找函数,不过不需要输入,直接遍历每个成员的每个信息并打印出来就达成目的啦。
//浏览所有联系人
void ReadContact(Contact* con)
{
assert(con);
//浏览
printf("%-20s\t%-5s\t%s\t%-30s\t%-12s\n", "姓名", "性别", "年龄", "地址", "号码");
for (int i = 0; i < con->sz; i++)
{
printf("%-20s\t%-5s\t%d\t%-30s\t%-12s\n", con->ContactMembers[i].Name,
con->ContactMembers[i].Sex,
con->ContactMembers[i].Age,
con->ContactMembers[i].Address,
con->ContactMembers[i].Number);
}
}
效果如下:
8.清空所有联系人
这里我们可以悄悄偷个懒...其实并不是,我们可以使用先前写好了的初始化通讯录的函数,直接调用就可以啦!
//清空所有联系人
void EmptyContact(Contact* con)
{
assert(con);
InitContact(con);
printf("重置成功!\n");
}
效果如下:
9.排序所有联系人
排序我们可以通过qsort函数来实现,将所有成员的数组名传递过去,即第一个成员结构体的地址,排序con->sz(成员数)次,每个元素大小为一个成员结构体的大小,而排序函数我们则通过比较两个结构体成员内容的大小即可,使用memcmp函数来实现对相同结构体内容的比较。
//排序函数
int Sort(const void* a, const void* b)
{
ContactMember* A = (ContactMember*)a;
ContactMember* B = (ContactMember*)b;
return memcmp(B, A, sizeof(ContactMember));
}
//排序所有联系人
void SortContact(Contact* con)
{
assert(con);
//排序
qsort(con->ContactMembers, con->sz, sizeof(con->ContactMembers[0]), Sort);
printf("排序完毕!\n");
}
具体效果如下:
文章来源:https://www.toymoban.com/news/detail-771106.html
六.源码
最后把源码分享出来,方便各位学习与交流。文章来源地址https://www.toymoban.com/news/detail-771106.html
1.ContactTest.c源码
#include "Contact.h"
void menu()
{
printf("*******************************\n");
printf("****** 通讯录 ******\n");
printf("****** 1.添加 2.删除 ******\n");
printf("****** 3.查找 4.修改 ******\n");
printf("****** 5.阅览 6.清空 ******\n");
printf("****** 7.排序 0.退出 ******\n");
printf("*******************************\n");
}
int main()
{
int s;
Contact con;
InitContact(&con);
do
{
menu();
scanf("%d", &s);
switch (s)
{
case 1:
AddContact(&con);
break;
case 2:
DelContact(&con);
break;
case 3:
SearchContact(&con);
break;
case 4:
ModifyContact(&con);
break;
case 5:
ReadContact(&con);
break;
case 6:
EmptyContact(&con);
break;
case 7:
SortContact(&con);
break;
case 0:
printf("已成功退出!\n");
break;
default:
printf("请输入正确的选项!\n");
}
} while (s);
return 0;
}
2.Contact.h源码
#pragma once
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#define MAX 1000
#define NAME_MAX 20
#define SEX_MAX 5
#define ADDR_MAX 30
#define TELE_MAX 12
//成员信息
typedef struct ContactMember
{
char Name[NAME_MAX];
char Sex[SEX_MAX];
int Age;
char Number[TELE_MAX];
char Address[ADDR_MAX];
}ContactMember;
typedef struct Contact
{
ContactMember ContactMembers[MAX];
int sz;
}Contact;
//初始化通讯录
void InitContact(Contact* con);
//增加联系人
void AddContact(Contact* con);
//删除指定联系人
void DelContact(Contact* con);
//查找指定联系人
void SearchContact(Contact* con);
//修改指定联系人
void ModifyContact(Contact* con);
//查看所有联系人
void ReadContact(Contact* con);
//清空所有联系人
void EmptyContact(Contact* con);
//排序所有联系人
void SortContact(Contact* con);
3.ContactRealize.c源码
#include "Contact.h"
//初始化成员信息
void InitContact(Contact* con)
{
con->sz = 0;
memset(con, 0, sizeof(con));
}
//查找目标成员位置
int FindName(Contact* con, char* name)
{
for (int i = 0; i < con->sz; i++)
{
if (strcmp(con->ContactMembers[i].Name, name) == 0)
{
return i;
}
}
return -1;
}
//大小排序(qsort实现)
int Sort(const void* a, const void* b)
{
ContactMember* A = (ContactMember*)a;
ContactMember* B = (ContactMember*)b;
return memcmp(B, A, sizeof(ContactMember));
}
void AddContact(Contact* con)
{
assert(con);
if (con->sz == MAX)
{
printf("通讯录已满!\n");
return;
}
printf("请输入姓名:");
scanf("%s", con->ContactMembers[con->sz].Name);
printf("请输入性别:");
scanf("%s", con->ContactMembers[con->sz].Sex);
printf("请输入年龄:");
scanf("%d", &con->ContactMembers[con->sz].Age);
printf("请输入住址:");
scanf("%s", con->ContactMembers[con->sz].Address);
printf("请输入号码:");
scanf("%s", con->ContactMembers[con->sz].Number);
printf("输入完毕!\n");
con->sz++;
}
void DelContact(Contact* con)
{
assert(con);
if (con->sz == 0)
{
printf("没有可以删除的目标!\n");
return;
}
printf("请输入目标删除人:");
char name[NAME_MAX];
scanf("%s", name);
int ret = FindName(con, name);
if (ret == -1)
{
printf("目标人物不存在!\n");
return;
}
memmove(con->ContactMembers + ret, con->ContactMembers + ret + 1, sizeof(con->ContactMembers[0]) * (con->sz - ret - 1));
printf("删除成功!\n");
con->sz--;
}
void SearchContact(Contact* con)
{
assert(con);
char name[NAME_MAX];
printf("请输入要查询的人:");
scanf("%s", name);
int ret = FindName(con, name);
if (ret == -1)
{
printf("查询目标不存在!\n");
return;
}
printf("%-20s\t%-5s\t%s\t%-30s\t%-12s\n", "姓名", "性别", "年龄", "地址", "号码");
printf("%-20s\t%-5s\t%d\t%-30s\t%-12s\n", con->ContactMembers[ret].Name,
con->ContactMembers[ret].Sex,
con->ContactMembers[ret].Age,
con->ContactMembers[ret].Address,
con->ContactMembers[ret].Number);
}
void ModifyContact(Contact* con)
{
assert(con);
char name[NAME_MAX];
printf("请输入要修改目标的姓名:");
scanf("%s", name);
int ret = FindName(con, name);
if (ret == -1)
{
printf("修改目标不存在!\n");
return;
}
printf("请输入要修改的姓名:");
scanf("%s", con->ContactMembers[ret].Name);
printf("请输入要修改的性别:");
scanf("%s", con->ContactMembers[ret].Sex);
printf("请输入要修改的年龄:");
scanf("%d", &con->ContactMembers[ret].Age);
printf("请输入要修改的地址:");
scanf("%s", con->ContactMembers[ret].Address);
printf("请输入要修改的号码:");
scanf("%s", con->ContactMembers[ret].Number);
printf("修改完毕!\n");
}
void ReadContact(Contact* con)
{
assert(con);
printf("%-20s\t%-5s\t%s\t%-30s\t%-12s\n", "姓名", "性别", "年龄", "地址", "号码");
for (int i = 0; i < con->sz; i++)
{
printf("%-20s\t%-5s\t%d\t%-30s\t%-12s\n", con->ContactMembers[i].Name,
con->ContactMembers[i].Sex,
con->ContactMembers[i].Age,
con->ContactMembers[i].Address,
con->ContactMembers[i].Number);
}
}
void EmptyContact(Contact* con)
{
assert(con);
InitContact(con);
printf("重置成功!\n");
}
void SortContact(Contact* con)
{
assert(con);
qsort(con->ContactMembers, con->sz, sizeof(con->ContactMembers[0]), Sort);
printf("排序完毕!\n");
}
到了这里,关于【C语言】通讯录管理系统(附图解、源码)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!