C语言-通讯录的实现

实现思路

建立3个文件,test.c,contact.c和contact.h
其中,test.c用于存放主体框架;
contact.h用于存放各功能函数的声明,需要用到的头文件,以及一些重命名变量;
contact.c用于存放实现各功能的模块。

整体的框架如下:
在这里插入图片描述

在整体框架搭建好的基础上,我们来填充各模块。

Test模块

模块框架如下:

在这里插入图片描述
模块代码如下:

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");
}
int main()
{
	int input = 0;
	//创建通讯录
	Contact con;
	//初始化通讯录
	InitContact(&con);//传递整个结构体

	do
	{
		menu();
		printf("请选择:>\n");
		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:
			QortContact(&con);
			break;
		case 0:
			printf("退出通讯录\n");
			break;
		default:
			printf("选择错误,请重新选择\n");
			break;

		}
	} while (input);
	return 0;
}

过渡部分

框架做完后,类型的定义 人的信息,包括姓名,年龄,性 别,地址,电话;
定义中出现的数字可以重定义为标识符常量;
做成结构体的形式,觉得类型名复杂,可以重定义;
创建通讯录,数组,100个;
test.c需要包含contact.h文件;
sz记录通讯录当前存放的信息的个数;
再创建一个结构体,将sz和通讯录的信息记录起来;
可以用typedef进行重命名;
重新创建通讯录con;


初始化通讯录
assert 断言;
简单粗暴的处理:直接赋值为0,即:Contact con={0};
或者封装一个函数:InitContact,参数传递为指针;
contact.c文件需要包含contact.h文件;
对于sz可以直接赋值为0,对于数组这多大的一块空间,可以使用memset进行初始化;
void * memset ( void * ptr, int value, size_t num );
sizeof(pc->data) pc 这里传递的是整个结构体 计算的是整个数组的大小;

模块框架如下:
在这里插入图片描述
模块代码如下

#define NAME_MAX 20
#define SEX_MAX 5
#define ADDRESS_MAX 30
#define TELEPHONE_MAX 12

#define MAX 100

//人的信息
typedef struct peopleinformaition
{
	char name[NAME_MAX];
	int age;
	char sex[SEX_MAX];
	char address[ADDRESS_MAX];
	char telephone[TELEPHONE_MAX];
}PeoInfo;

//通讯录
typedef struct Contact
{
	PeoInfo data[MAX];//可以存放max个人的信息
	int sz;//sz 表示当前已存放的人的个数
}Contact;
/初始化通讯录
void InitContact(Contact* pc)
{
	assert(pc);
	memset(pc->data,0,sizeof(pc->data));
	pc->sz = 0;
}

AddContact模块

增加加通讯录;
assert 断言;
放置到下标为sz的位置上;
先判断通讯录是否已满MAX,若已满,renturn返回,什么都不携带;
增加一个人的信息:printf和scanf;
pc->data[pc->sz]是一个结构体,name是一个数组;

模块框架如下:
在这里插入图片描述
模块代码如下:

//增加通讯录
void AddContact(Contact* pc)
{
	assert(pc);
	if (pc->sz==MAX)
	{
		printf("通讯录已满\n");
	}
	printf("请输入人的姓名\n");
	scanf("%s",pc->data[pc->sz].name);
	printf("请输入人的年龄\n");
	scanf("%d", &(pc->data[pc->sz].age));
	printf("请输入人的性别\n");
	scanf("%s", pc->data[pc->sz].sex);
	printf("请输入人的地址\n");
	scanf("%s", pc->data[pc->sz].address);
	printf("请输入人的电话\n");
	scanf("%s", pc->data[pc->sz].telephone);

	pc->sz++;
}

ShowContact模块

显示通讯录;
assert 断言;
for循环打印,一个printf;
\t 水平制表符,相当于tab;
%20s 控制宽度;
%-20s 左对齐,默认为右对齐;
一个汉字在存储的时候需要占2个字节的空间;
优化:可以先打印出表头 表头中的年龄是字符串,需要改动%d为%s;
打印部分加上const ;

模块框架如下:
在这里插入图片描述
模块代码如下:

//显示通讯录
void ShowContact(const Contact* pc)
{
	assert(pc);
	int i = 0;
	printf("%-15s\t%-2s\t%-s\t%-25s\t%-12s\n", "姓名", "年龄", "性别", "地址", "电话");
	for (i=0;i<pc->sz;i++)
	{
		printf("%-15s\t%-2d\t%-s\t%-25s\t%-12s\n",pc->data[i].name,
			pc->data[i].age,
			pc->data[i].sex,
			pc->data[i].address,
			pc->data[i].telephone);
	}
}

DelContact模块

删除通讯录;
没有元素就不能删除了;
找到要删除的人;
输入要删除人的名字,用strcmp对比;
找到之后,用del记住它的下标;
删除的方式:后面的元素向前覆盖或者最后一个元素移动到这里覆盖掉这个元素;
选择后面的元素向前覆盖;
i+1的元素赋给i,sz的最大值为‘sz-1’;
sz–;
给出反馈;
封装查找的动作,为函数findbyname( 参1,参2),找到给出下标,没找到返回-1;

模块框架如下:
在这里插入图片描述
模块代码如下:

int FindByName(const Contact* pc, char name[NAME_MAX])
{
	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)
{
	assert(pc);
	char name[NAME_MAX];
	if (pc->sz==0)
	{
		printf("通讯录为空,不能删除\n");
		return;
	}
	//查找这个人
	printf("请输入要删除人的名字\n");
	scanf("%s",name);
	int ret = FindByName(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");
}

SearchContact模块

7.查找通讯录;
可以加const;
输入要查找人的名字;
调用FindByName函数;
判断人的信息是否存在;
若存在,用pos标记,打印信息;

模块框架如下:
在这里插入图片描述

模块代码如下:

//查找通讯录
void SearchContact(const Contact* pc)
{
	assert(pc);
	char name[NAME_MAX];
	printf("请输入要查找人的名字\n");
	scanf("%s",name);
	int pos = FindByName(pc,name);
	if (-1==pos)
	{
		printf("要查找人的信息不存在");
		return;
	}
	printf("%-15s\t%-2s\t%-s\t%-25s\t%-12s\n", "姓名", "年龄", "性别", "地址", "电话");
	printf("%-15s\t%-2d\t%-s\t%-25s\t%-12s\n", pc->data[pos].name,
		pc->data[pos].age,
		pc->data[pos].sex,
		pc->data[pos].address,
		pc->data[pos].telephone);
}

ModifyContact模块

8.修改通讯录;
先查找这个人的信息,再去修改;
输入要查找人的名字;
调用FindByName函数;
判断人的信息是否存在;
修改信息就是重新再录一遍;
增加一个人的信息:printf和scanf;
pc->data[pc->sz]是一个结构体,name是一个数组;
提示信息,修改完成;

模块的框架如下:
在这里插入图片描述
模块的代码如下:

//修改通讯录
void ModifyContact(Contact* pc)
{
	assert(pc);
	char name[NAME_MAX];
	printf("请输入要修改人的名字\n");
	scanf("%s", name);
	int pos = FindByName(pc, name);
	if (-1 == pos)
	{
		printf("要修改人的信息不存在");
		return;
	}
	printf("请输入人的姓名\n");
	scanf("%s", pc->data[pos].name);
	printf("请输入人的年龄\n");
	scanf("%d", &(pc->data[pos].age));
	printf("请输入人的性别\n");
	scanf("%s", pc->data[pos].sex);
	printf("请输入人的地址\n");
	scanf("%s", pc->data[pos].address);
	printf("请输入人的电话\n");
	scanf("%s", pc->data[pos].telephone);

}

SortContact模块

排序通讯录
按年龄进行排序;
排序,传递给qsort的不能是单个元素,传递数组;
排完序后打印出来;

模块框架如下:
在这里插入图片描述

模块代码如下:

int CompareByAge(const void* a, const void* b)
{
	return ((PeoInfo*)a)->age- ((PeoInfo*)b)->age;
}
//排序通讯录
void QortContact(Contact* pc)
{
	assert(pc);
	qsort(pc->data, pc->sz, sizeof(pc->data[0]), CompareByAge);
	printf("排序后的通讯录\n");
	int i = 0;
	printf("%-15s\t%-2s\t%-s\t%-25s\t%-12s\n", "姓名", "年龄", "性别", "地址", "电话");
	for (i = 0; i < pc->sz; i++)
	{
		printf("%-15s\t%-2d\t%-s\t%-25s\t%-12s\n", pc->data[i].name,
			pc->data[i].age,
			pc->data[i].sex,
			pc->data[i].address,
			pc->data[i].telephone);
	}
}

通讯录全部代码

test.c

#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");
}
int main()
{
	int input = 0;
	//创建通讯录
	Contact con;
	//初始化通讯录
	InitContact(&con);//传递整个结构体

	do
	{
		menu();
		printf("请选择:>\n");
		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:
			QortContact(&con);
			break;
		case 0:
			printf("退出通讯录\n");
			break;
		default:
			printf("选择错误,请重新选择\n");
			break;

		}
	} while (input);
	return 0;
}

contact.h

#pragma once
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>

#define NAME_MAX 20
#define SEX_MAX 5
#define ADDRESS_MAX 30
#define TELEPHONE_MAX 12

#define MAX 100

//人的信息
typedef struct peopleinformaition
{
	char name[NAME_MAX];
	int age;
	char sex[SEX_MAX];
	char address[ADDRESS_MAX];
	char telephone[TELEPHONE_MAX];
}PeoInfo;

//通讯录
typedef struct Contact
{
	PeoInfo data[MAX];//可以存放max个人的信息
	int sz;//sz 表示当前已存放的人的个数
}Contact;

//初始化通讯录
void InitContact(Contact* pc);

//增加通讯录
void AddContact(Contact* pc);

//显示通讯录
void ShowContact(const Contact* pc);

//删除通讯录
void DelContact(Contact* pc);

//查找通讯录
void SearchContact(const Contact* pc);

//修改通讯录
void ModifyContact(Contact* pc);

//排序通讯录
void QortContact(Contact* pc);

contact.c


#include "contact.h"

//初始化通讯录
void InitContact(Contact* pc)
{
	assert(pc);
	memset(pc->data,0,sizeof(pc->data));
	pc->sz = 0;
}

//增加通讯录
void AddContact(Contact* pc)
{
	assert(pc);
	if (pc->sz==MAX)
	{
		printf("通讯录已满\n");
	}
	printf("请输入人的姓名\n");
	scanf("%s",pc->data[pc->sz].name);
	printf("请输入人的年龄\n");
	scanf("%d", &(pc->data[pc->sz].age));
	printf("请输入人的性别\n");
	scanf("%s", pc->data[pc->sz].sex);
	printf("请输入人的地址\n");
	scanf("%s", pc->data[pc->sz].address);
	printf("请输入人的电话\n");
	scanf("%s", pc->data[pc->sz].telephone);

	pc->sz++;
}

//显示通讯录
void ShowContact(const Contact* pc)
{
	assert(pc);
	int i = 0;
	printf("%-15s\t%-2s\t%-s\t%-25s\t%-12s\n", "姓名", "年龄", "性别", "地址", "电话");
	for (i=0;i<pc->sz;i++)
	{
		printf("%-15s\t%-2d\t%-s\t%-25s\t%-12s\n",pc->data[i].name,
			pc->data[i].age,
			pc->data[i].sex,
			pc->data[i].address,
			pc->data[i].telephone);
	}
}


int FindByName(const Contact* pc, char name[NAME_MAX])
{
	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)
{
	assert(pc);
	char name[NAME_MAX];
	if (pc->sz==0)
	{
		printf("通讯录为空,不能删除\n");
		return;
	}
	//查找这个人
	printf("请输入要删除人的名字\n");
	scanf("%s",name);
	int ret = FindByName(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)
{
	assert(pc);
	char name[NAME_MAX];
	printf("请输入要查找人的名字\n");
	scanf("%s",name);
	int pos = FindByName(pc,name);
	if (-1==pos)
	{
		printf("要查找人的信息不存在");
		return;
	}
	printf("%-15s\t%-2s\t%-s\t%-25s\t%-12s\n", "姓名", "年龄", "性别", "地址", "电话");
	printf("%-15s\t%-2d\t%-s\t%-25s\t%-12s\n", pc->data[pos].name,
		pc->data[pos].age,
		pc->data[pos].sex,
		pc->data[pos].address,
		pc->data[pos].telephone);
}

//修改通讯录
void ModifyContact(Contact* pc)
{
	assert(pc);
	char name[NAME_MAX];
	printf("请输入要修改人的名字\n");
	scanf("%s", name);
	int pos = FindByName(pc, name);
	if (-1 == pos)
	{
		printf("要修改人的信息不存在");
		return;
	}
	printf("请输入人的姓名\n");
	scanf("%s", pc->data[pos].name);
	printf("请输入人的年龄\n");
	scanf("%d", &(pc->data[pos].age));
	printf("请输入人的性别\n");
	scanf("%s", pc->data[pos].sex);
	printf("请输入人的地址\n");
	scanf("%s", pc->data[pos].address);
	printf("请输入人的电话\n");
	scanf("%s", pc->data[pos].telephone);

}


int CompareByAge(const void* a, const void* b)
{
	return ((PeoInfo*)a)->age- ((PeoInfo*)b)->age;
}
//排序通讯录
void QortContact(Contact* pc)
{
	assert(pc);
	qsort(pc->data, pc->sz, sizeof(pc->data[0]), CompareByAge);
	printf("排序后的通讯录\n");
	int i = 0;
	printf("%-15s\t%-2s\t%-s\t%-25s\t%-12s\n", "姓名", "年龄", "性别", "地址", "电话");
	for (i = 0; i < pc->sz; i++)
	{
		printf("%-15s\t%-2d\t%-s\t%-25s\t%-12s\n", pc->data[i].name,
			pc->data[i].age,
			pc->data[i].sex,
			pc->data[i].address,
			pc->data[i].telephone);
	}
}
  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值