通讯录:存放人的信息,包括姓名,年龄,性别,电话,地址
功能如下:
- 存放100个人的信息
- 增加联系人
- 删除指定联系人
- 查找联系人
- 修改信息
- 排序
- 显示
分析:要存放一个人的多项信息,我们要使用结构体类型;要存放100个人的信息,我们要使用数组,并且这个数组中每个元素的类型是结构体类型。
我们可以将通讯录当作一个结构体,其中包括存放个人信息的数组和当前通讯录中的实际人数
对于数组的大小,我们可以使用#define定义常量,便于后期代码的修改
#define MAX 100
#define MAX_Name 20
#define MAX_Sex 10
#define MAX_Tele 12
#define MAX_Addr 30
//结构声明
typedef struct PeoInfo
{
char name[MAX_Name];
int age;
char sex[MAX_Sex];
char tele[MAX_Tele];
char addr[MAX_Addr];
}PeoInfo;
typedef struct Contact
{
PeoInfo data[MAX];//能容纳100个人的信息的通讯录
int count;//当前通讯录的实际人数
}Contact;
接着搭建通讯录的基本框架
void meau()
{
printf("********** 0.Exit **********\n");
printf("********** 1.Add ***********\n");
printf("********** 2.Delete *********\n");
printf("********** 3.Search *********\n");
printf("********** 4.Modify **********\n");
printf("********** 5.Show ***********\n");
printf("********** 6.Sort ***********\n");
}
int main()
{
int input = 0;
//通讯录初始化
do
{
meau();//菜单函数
printf("请选择:\n");
scanf("%d", &input);
switch (input)
{
case 0:
printf("退出通讯录\n");
break;
case 1:
//添加联系人
break;
case 2:
//删除联系人
break;
case 3:
//查找联系人
break;
case 4:
//修改联系人
break;
case 5:
//联系人排序
break;
case 6:
//打印联系人
break;
default:
printf("输入错误,请重新输入:\n");
break;
}
} while (input);
return 0;
}
基本框架搭建好之后,我们就实现每一个功能,并将其封装成函数
第一步:初始化通讯录
通讯录中实际联系人的个数为0
//初始化通讯录
void InitContact(Contact* pc)
{
assert(pc);
pc->count = 0;
memset(pc->data, 0, sizeof(pc->data));
}
添加联系人
注意:当通讯录中的实际联系人个数达到100时,即证明通讯录存满不能继续添加
//添加联系人
void AddContact(Contact* pc)
{
assert(pc);
if (pc->count == MAX)
{
printf("通讯录已满\n");
return;//直接返回
}
else
{
printf("请输入姓名:");
scanf("%s", pc->data[pc->count].name);
printf("请输入年龄:");
scanf("%d", &pc->data[pc->count].age);
printf("请输入性别:");
scanf("%s", pc->data[pc->count].sex);
printf("请输入电话:");
scanf("%s", pc->data[pc->count].tele);
printf("请输入地址:");
scanf("%s", pc->data[pc->count].addr);
//添加成功
pc->count++;
printf("添加成功\n");
}
}
删除联系人
注意:当通讯录中的实际联系人个数为0时,即证明通讯录中没有联系人不能继续删除
//删除联系人
void DeleteContact(Contact* pc)
{
assert(pc);
char name[MAX_Name] = { 0 };
printf("请输入要删除的联系人姓名:");
scanf("%s", name);
//查找
int pos = find_by_name(pc, name);
if (pos == -1)
{
printf("要删除的联系人不存在\n");
return;
}
//找到联系人,下标为pos
else
{
int i = 0;
for (i = pos; i < pc->count - 1; i++)
{
pc->data[i] = pc->data[i + 1];
}
pc->count--;//最后一个元素访问不到,防止数组越界
printf("删除成功\n");
}
}
我们在删除联系人,查找联系人,修改指定联系人信息时都需要查找指定联系人,所以我们可以将查找联系人封装成一个函数,这了是按照姓名查找联系人,同理可以按照电话号码,地址等查找
static修饰函数:对于一个工程中的两个.c文件,一个函数本来具有外部链接属性,当这个函数被static修饰后,外部链接属性就变成了外部链接属性,这时函数只能在自己所在的源文件内部使用,其他文件无法使用
//按姓名查找联系人
static int find_by_name(Contact* pc, char name[])
{
assert(pc);
int i = 0;
for (i = 0; i < pc->count; i++)
{
if (0 == strcmp(pc->data[i].name, name))
{
return i;
}
}
return -1;//没找到联系人
}
查找联系人
这里我们按照姓名查找联系人,同理可以按照电话号码,地址等查找
//查找联系人
void SearchContact(Contact* pc)
{
assert(pc);
char name[MAX_Name] = { 0 };
printf("请输入要查找的联系人的姓名:");
scanf("%s", name);
//查找
int pos = find_by_name(pc, name);
if (pos == -1)
{
printf("要查找的联系人不存在\n");
return;
}
//找到联系人,下标为pos,删除
else
{
printf("%-20s\t%-5d\t%-5s\t%-12s\t%-30s\n", pc->data[pos].name,
pc->data[pos].age,
pc->data[pos].sex,
pc->data[pos].tele,
pc->data[pos].addr);
}
}
修改指定联系人
这里我们按照姓名查找联系人,同理可以按照电话号码,地址等查找,找到之后重新录入这个联系人的所有信息
//修改指定联系人信息
void ModifyContact(Contact* pc)
{
assert(pc);
char name[MAX_Name] = { 0 };
printf("请输入要修改的联系人的姓名:");
scanf("%s", name);
//查找
int pos = find_by_name(pc, name);
if (pos == -1)
{
printf("要修改的联系人不存在\n");
return;
}
//找到联系人,下标为pos,修改
else
{
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].tele);
printf("请输入地址:");
scanf("%s", pc->data[pos].addr);
//修改成功
printf("修改成功\n");
}
}
显示所有联系人
遍历数组,已知当前通讯录的实际人数为count
//打印联系人信息
void ShowContact(Contact* pc)
{
assert(pc);
int i = 0;
printf("%-20s\t%-5s\t%-5s\t%-12s\t%-30s\n", "姓名", "年龄", "性别", "电话", "地址");
for (i = 0; i < pc->count; i++)
{
printf("%-20s\t%-5d\t%-5s\t%-12s\t%-30s\n", pc->data[i].name,
pc->data[i].age,
pc->data[i].sex,
pc->data[i].tele,
pc->data[i].addr);
}
}
对联系人进行排序
使用qsort函数进行排序,比较函数为比较姓名的函数,同理可以比较电话号码,地址等
//对联系人进行排序
//按照姓名进行排序
int cmp_by_name(const void* e1, const void* e2)
{
return strcmp(((PeoInfo*)e1)->name, ((PeoInfo*)e2)->name);
}
void SortContact(Contact* pc)
{
assert(pc);
qsort(pc->data, pc->count, sizeof(PeoInfo), cmp_by_name);
printf("排序成功\n");
}
contact.h头文件中包含头文件,#define定义的常量,结构声明,函数声明
.c文件中如需使用,直接包含头文件contact.h即可
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
//头文件
#include<stdio.h>
#include<assert.h>
#include<string.h>
#include<stdlib.h>
#define MAX 100
#define MAX_Name 20
#define MAX_Sex 10
#define MAX_Tele 12
#define MAX_Addr 30
//结构声明
typedef struct PeoInfo
{
char name[MAX_Name];
int age;
char sex[MAX_Sex];
char tele[MAX_Tele];
char addr[MAX_Addr];
}PeoInfo;
typedef struct Contact
{
PeoInfo data[MAX];
int count;//当前通讯录的实际人数
}Contact;
//函数声明
//添加联系人
void AddContact(Contact* pc);
//删除联系人
void DeleteContact(Contact* pc);
//查找联系人
void SearchContact(Contact* pc);
//修改指定联系人信息
void ModifyContact(Contact* pc);
//打印联系人信息
void ShowContact(Contact* pc);
//对联系人进行排序
void SortContact(Contact* pc);
完整代码:
Project_23_2_7/Project_23_2_7 · 李斯啦果/我的代码 - 码云 - 开源中国 (gitee.com)