目录
4.添加联系人和显示当前储存的联系人(AddContact和ShowContact)
5.查找联系人(FindContact和SearchContact)
😇前言😇:
本篇博客是对前面C语言知识的加强训练——创建一个自己的通讯录(简单),类似于前面的博客讲过的扫雷💣和三子棋♟️,这篇博客里面的涉及到的库函数会单独出一篇博客讲解用法示例🐇。
🛰️博客主页:助力每一只ikun
🛰️感谢支持:👍点赞🙌收藏✍️留言
各位家人更新不易,欢迎大家提出问题建议,你们的👍点赞👉评论👏支持对我来说很重要,那是我坚持下去的动力❤️🔥需要源代码的可以去Git仓库下载,里面记录了我学习成长的代码。
点击👉:GIT💬连接
😸本文库函数博客连接😸:
一、通讯录的设计思路
相信大家都用过手机中的通讯录功能,让我们回忆下手机通讯录中可使用的功能。
我们在本篇博客中基本简单实现了前六个功能,后期将补充排序功能,各位大佬也可以根据自己的思路优化功能💯💯💯。
二、程序设计
1.打印菜单
一如既往的,一个菜单显示出你程序的基本可选择功能,尽量简介易懂。
大家可以根据自己的喜好设计界面,源代码如下:
#include <stdio.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");
}
int main()
{
int input = 0;
do
{
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
break;
case 6:
break;
case 0:
printf("退出通讯录\n");
break;
default:
printf("输入错误,请重新输入:>\n");
break;
}
} while (input);
return 0;
}
之所以选择do...while 循环语句,是为了保证了我们程序的多次执行。并且我们通过将输入值 input 作为循环判断条件,既能够减少变量的创建从而节省了空间,也避免了因输入错误导致直接跳出执行。同时,通过借助 switch 分支语句,我们也实现了对通讯录不同功能的调用和对输入选择的合法性检测。
2.创建结构体
为什么要创建结构体?答案其实很简单,因为你的通讯录所包含的信息是不同类型的信息:如输入名字和性别这一类信息我们就需要一个字符型数组来储存,而年龄就需要用一个整形变量储存
代码如下:
#define MAX 100
#define NAME_MAX 20
#define SEX_MAX 5
#define ADDR_MAX 30
#define TELE_MAX 12
// 人的信息
typedef struct Peoinfo
{
char name[NAME_MAX];
int age;
char sex[SEX_MAX];
char addr[ADDR_MAX];
char tele[TELE_MAX];
}Peoinfo;
typedef struct Contact
{
Peoinfo data[MAX];//最多储存一百个人的信息
int sz = 0; //记录当前储存信息个数的变量
}Contact;
细心的读者会发现我们利用了宏定义进行常量的重新命名定义,这样做可以方便以后对我们制作的通讯录最大储存的维护和修改。
3.初始化通讯录
我们在创建完通讯录后要对其进行初始化,不然随机值很容易导致程序运行出错误。
void IintContact(Contact* pc)
{
pc->sz = 0;
memset(pc->data, 0, sizeof(pc->data));
//使用memeset函数将p->data所指向的空间中的数据初始化为0
//操作的空间大小为sizeof函数所计算出的p->data所指向空间的大小,即整个无联系人数据的结构体数组data所占的空间的大小
}
4.添加联系人和显示当前储存的联系人(AddContact和ShowContact)
我们的函数命名是尽量和实现的功能相结合这样可以提高程序的可读性
首先我们在函数调用时,因为我们要对内存中的数据进行实际的修改,故优先使用传址调用,应当向函数传入存放着结构体数组地址(数组名为首元素地址)与计数变量 sz 的 contact 类型结构体变量 con 的地址:
AddContact(&con);
紧接着的是对AddContact函数的实现,我们要实现的功能是向通讯录中添加联系人的基本信息,这里我们要将联系人的基本信息依次储存在我们所创建的结构体中,我们是根据地址寻找到所储存的位置,所以我们对于通讯录的访问是通过指针进行的,信息的存入地址一定是对应的存入地址,数组应当使用指针进行访问,变量则应当使用取地址操作符进行访问:
代码如下:
void AddContact(Contact* 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].addr);
printf("请输入电话:>");
scanf("%s", pc->data[pc->sz].tele);
pc->sz++;
}
接下来我们写的是ShowContact函数,之所以先编写这个函数是因为这样可以实时的检测我们的程序运行结果是否有错误,方便我们及时更改程序。
函数设计思路如下:
我们将所有的内存依次遍历打印出所有用AddContact函数添加到结构体中的信息。
void ShowContact(const Contact* pc)
{
int i = 0;
printf("%-8s\t%-4s\t%-5s\t%-10s\t%-12s\n", "姓名", "年龄", "性别", "地址", "电话");
for (i = 0; i < pc->sz; i++)
{
printf("%-8s\t%-4d\t%-5s\t%-10s\t%-12s\n", pc->data[i].name,
pc->data[i].age, pc->data[i].sex, pc->data[i].addr, pc->data[i].tele);
}
}//%-8s\t这类操作符是为了打印结果更加美观
5.查找联系人(FindContact和SearchContact)
通过观察功能特点,我们发现删除,修改功能都需要建立在查找功能上实现,所以我们接下来选择编写查找功能
FindContact函数设计思路:
通过对比所输入的联系人与当前所储存联系人的相同信息进行筛选,如姓名,电话等,我所选择的是比较相同的姓名,我们选择设计一个char类型的数组name来储存所要查找的联系人姓名,通过strcmp函数的返回值判断是否相同,相同则返回当前下标,否则则返回-1.
int FindName(const 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;
}
//在利用FindContact判断完有无相同对象就可以利用SearchContact函数打印
void SearchContact(const Contact* pc)
{
char name[NAME_MAX] = { 0 };
printf("请输入要查找人的名字:>");
scanf("%s", name);
int pos = FindName(pc, name);
if (-1 == pos)
{
printf("要查找的人不存在\n");
return;
}
//打印信息
printf("%-8s\t%-4s\t%-5s\t%-10s\t%-12s\n", "姓名", "年龄", "性别", "地址", "电话");
printf("%-8s\t%-4d\t%-5s\t%-10s\t%-12s\n", pc->data[pos].name,
pc->data[pos].age, pc->data[pos].sex, pc->data[pos].addr, pc->data[pos].tele);
}
6.删除联系人(DelContact)
DelContact函数设计思路:
利用上述FindContact函数的基础上,进行删除或者(覆盖),这里我们选择最简单的覆盖。
void DelContact(Contact* pc)
{
char name[NAME_MAX] = { 0 };
if (pc->sz == 0)
{
printf("通讯录为空,无法删除\n");
return;
}
//查找删除对象
printf("请输入删除对象的名字:>");
scanf("%s", name);
int ret = FindName(pc, name);
if (-1 == ret)
{
printf("删除对象不存在\n");
return;
}
int i = 0;
//删除
for (i = ret; i < pc->sz - 1; i++)
{
pc->data[i] = pc->data[i + 1];
}
pc->sz--;
printf("删除成功\n");
}
7.修改联系人(ModifyContact)
在FindContact函数的基础上,当查找到后我们重新输入对信息进行覆盖替换。
void ModifyContact(Contact* pc)
{
assert(pc);
char name[NAME_MAX] = { 0 };
printf("请输入要修改人的名字:>");
scanf("%s", name);
int pos = FindName(pc, name);
if (-1 == pos)
{
printf("要修改的人不存在\n");
return;
}
printf("请输入名字:>");
scanf("%s", pc->data[pos].name);
printf("请输入年龄:>");
scanf("%d", &(pc->data[pos].age));
printf("请输入性别:>");
scanf("%s", pc->data[pos].sex);
printf("请输入地址:>");
scanf("%s", pc->data[pos].addr);
printf("请输入电话:>");
scanf("%s", pc->data[pos].tele);
printf("修改完成\n");
}
三、完整代码
test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "Contacts.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");
}
int main()
{
int input = 0;
//创建通讯录
Contact con;
//初始化通讯录
IintContact(&con);
do
{
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case 1:
AddContact(&con);
break;
case 2:
DelContact(&con);
break;
case 3:
SearchContact(&con);
break;
case 4:
ModifyContact(&con);
break;
case 5:
ShowContact(&con);
break;
case 6:
break;
case 0:
printf("退出通讯录\n");
break;
default:
printf("输入错误,请重新输入:>\n");
break;
}
} while (input);
return 0;
}
Contacts.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "Contacts.h"
void IintContact(Contact* pc)
{
pc->sz = 0;
memset(pc->data, 0, sizeof(pc->data));
}
void AddContact(Contact* 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].addr);
printf("请输入电话:>");
scanf("%s", pc->data[pc->sz].tele);
pc->sz++;
}
void ShowContact(const Contact* pc)
{
int i = 0;
printf("%-8s\t%-4s\t%-5s\t%-10s\t%-12s\n", "姓名", "年龄", "性别", "地址", "电话");
for (i = 0; i < pc->sz; i++)
{
printf("%-8s\t%-4d\t%-5s\t%-10s\t%-12s\n", pc->data[i].name,
pc->data[i].age, pc->data[i].sex, pc->data[i].addr, pc->data[i].tele);
}
}
int FindName(const 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] = { 0 };
if (pc->sz == 0)
{
printf("通讯录为空,无法删除\n");
return;
}
//查找删除对象
printf("请输入删除对象的名字:>");
scanf("%s", name);
int ret = FindName(pc, name);
if (-1 == ret)
{
printf("删除对象不存在\n");
return;
}
int i = 0;
//删除
for (i = ret; i < pc->sz - 1; i++)
{
pc->data[i] = pc->data[i + 1];
}
pc->sz--;
printf("删除成功\n");
}
void SearchContact(const Contact* pc)
{
char name[NAME_MAX] = { 0 };
printf("请输入要查找人的名字:>");
scanf("%s", name);
int pos = FindName(pc, name);
if (-1 == pos)
{
printf("要查找的人不存在\n");
return;
}
//打印信息
printf("%-8s\t%-4s\t%-5s\t%-10s\t%-12s\n", "姓名", "年龄", "性别", "地址", "电话");
printf("%-8s\t%-4d\t%-5s\t%-10s\t%-12s\n", pc->data[pos].name,
pc->data[pos].age, pc->data[pos].sex, pc->data[pos].addr, pc->data[pos].tele);
}
void ModifyContact(Contact* pc)
{
assert(pc);
char name[NAME_MAX] = { 0 };
printf("请输入要修改人的名字:>");
scanf("%s", name);
int pos = FindName(pc, name);
if (-1 == pos)
{
printf("要修改的人不存在\n");
return;
}
printf("请输入名字:>");
scanf("%s", pc->data[pos].name);
printf("请输入年龄:>");
scanf("%d", &(pc->data[pos].age));
printf("请输入性别:>");
scanf("%s", pc->data[pos].sex);
printf("请输入地址:>");
scanf("%s", pc->data[pos].addr);
printf("请输入电话:>");
scanf("%s", pc->data[pos].tele);
printf("修改完成\n");
}
Contacts.h
#pragma once
#include <stdio.h>
#include <string.h>
#include <assert.h>
#define MAX 100
#define NAME_MAX 20
#define SEX_MAX 5
#define ADDR_MAX 30
#define TELE_MAX 12
// 人的信息
typedef struct Peoinfo
{
char name[NAME_MAX];
int age;
char sex[SEX_MAX];
char addr[ADDR_MAX];
char tele[TELE_MAX];
}Peoinfo;
typedef struct Contact
{
Peoinfo data[100];
int sz = 0;
}Contact;
//初始化通讯录
void IintContact(Contact* pc);
//增加联系人
void AddContact(Contact* pc);
//显示联系人
void ShowContact(const Contact* pc);
//删除联系人
void DelContact(Contact* pc);
//查找联系人
void SearchContact(const Contact* pc);
int FindName(const Contact* pc, char name[]);
//修改联系人
void ModifyContact(Contact* pc);
总结
大概的思路和实现的功能就是这些,这只是个极其简易的通讯录,并不能像手机里的那么贴心。可优秀的app都是从这些小程序一步步演变的。学习也一样,不积跬步,无以至千里。