C语言实现通讯录(低配版)

一.准备

首先我们要创建三个文件:
1.text.c主文件
2.contact.c文件,这个主要放的是实现通讯录有关的文件
3.contact.h文件,头文件,有函数的声明,结构体定义和一些宏定义

二.主文件

#include "contact.h"

void menu()
{
	printf("****************************************\n");
	printf("********  1.添加      2.删除    ********\n");
	printf("********  3.全部删除  4.修改    ********\n");
	printf("********  5.查找      6.显示    ********\n");
	printf("********  7.排序      0.退出    ********\n");
	printf("****************************************\n");
}

int main()
{
	int input = 0;
	struct Contact con;
	//定义一个结构体con,结构体信息在contact.h里面

	//初始化通讯录信息
	Init_Contact(&con);
	do
	{
		menu();
		printf("请输入->");
		scanf("%d", &input);
		switch (input)
		{
		case ADD:
			Add_contact(&con);
			break;
		case DELETE:
			Delete_Contact(&con);
			//全部删除就相当于初始化了
			break;
		case DELETE_ALL:
			Init_Contact(&con);
			break;
		case AMEND:
			Amend_Contact(&con);
			break;
		case FIND:
			Find_Contact(&con);
			break;
		case SHOW:
			Show_Contact(&con);
			break;
		case SORT:
			Sort_Contact(&con);
			break;
		case EXIT:
			break;
		default:
			printf("输入错误,请重新输入->\n");
			break;
		}
	} while (input);
	return 0;
}

这个放在主文件里。

main函数的主要框架是do while函数。这样就可以在执行一次循环之后,继续执行我们想要的内容。而不是在执行一次循环之后就退出去。

循环里面是switch语句。我们的通讯录里有8个命令:添加,删除,全部删除,修改,寻找,展示,排序,退出。
EXIT,ADD,DELETE,DELETE_ALL,AMEND,FIND,SHOW,SORT。这些都是枚举变量,是在contact.h里面定义好的。这些变量的值从0开始。
我们通过定义的input变量来控制这些。假设输入1,input的值就是1,对应的就是实现ADD对应的函数。
每个命令都对应这一个函数,这些函数在contact.c文件里实现。

程序一运行肯定要先初始化,初始化的代码放在contact.c文件里。
为了让使用者知道每个命令对应的按键,所以要有目录menu
menu函数自己定义好就行,这个函数比较简单,直接放在main函数上面就行。

#include “contact.h”
因为我们写的大部分参数和一些定义都在contact.h文件里,所以先包含contact.h,代码才能运行。

三.contact.h文件

3.1需要用到的宏定义,和函数所需的头文件

#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>

#define  SIZE      10      //通讯录的大小,能装10个成员的信息
#define  NAME      20      //联系人名字数组的长度
#define  SEX       8       //联系人性别数组的长度
#define  PHONE     12      //联系人电话数组的长度
#define  LOCATION  15      //联系人地址数组的长度

3.2结构体定义

enum catalog
//枚举
{
	EXIT,      //退出
	ADD,       //添加联系人信息
	DELETE,    //删除联系人信息
	DELETE_ALL,//删除所有人信息
	AMEND,     //修改联系人信息
	FIND,      //查找联系人
	SHOW,      //显示所有联系人信息
	SORT,      //排序联系人信息
};

//联系人信息
struct Contact_Person
{
	char name[NAME];          //联系人姓名
	char sex[SEX];             //联系人性别
	char phone[PHONE];        //联系人电话
	char location[LOCATION];  //联系人地址
};

//通讯录
struct Contact
{
	int size;
	struct Contact_Person data[SIZE];
};

主要讲一下结构体struct Contact

size是为了以后函数的使用,记录当前通讯录里联系人的个数。在初始化是size为0.

struct Contact_Person data[SIZE];是一个数组
数组里有SIZE个成员,SIZE已经在上面宏定义好了,可自己调整大小。就是说通讯录最多能装SIZE个成员。每个成员的类型都是struct Contact_Person类型的。
struct Contact_Person是我们定义好的结构体。

总结一下:
我们把每个联系人的信息:姓名,性别,手机号,地址封装在一个结构体(struct Contact_Person)里。
然后我们在定义一个更大的结构体里面有成员size,是为了记录当前成员的个数。还有一个成员是一个数组,数组的每个成员都是struct Contact_Person类型的。也就是数组里的每个元素都是一个联系人的信息

3.3函数的声明

//初始化通讯录信息
void Init_Contact(struct Contact* con);

//添加联系人信息
void Add_contact(struct Contact* con);

//显示所有联系人信息
void Show_Contact(struct Contact* con);

//删除指定联系人信息
void Delete_Contact(struct Contact* con);

//查找联系人
void Find_Contact(struct Contact* con);

//修改联系人信息
void Amend_Contact(struct Contact* con);

//排序联系人信息
void Sort_Contact(struct Contact* con);

这些就是我们在contact.c文件用到的函数

四.contact.c文件

4.1初始化通讯录信息Init_Contact

void Init_Contact(struct Contact* con)
{
	con->size = 0;
	memset(con->data, 0, sizeof(con->data));
}

我们将结构体里的size设置为0,说明此时通讯录里还没有成员

memset函数:
将结构体data数组里面的数据全部设置成0。

memset函数的用法:

void * memset ( void * ptr, int value, size_t num );
ptr:需要更改(填充)数据的内存块的地址,上面我们要更改的是数组data。
value:我们要把这个内存块的内容更改成value,上面我们要把数组里的内容变成0
size_t num:我们要把这个内存块的num个字节的内容改成value。上面我们用到的是sizeof(con->data),就是把整个数组大小的内容设置成0.这样就达到初始话的效果了。

4.2添加联系人信息Add_contact

void Add_contact(struct Contact* con)
{
	system("cls");
	if (con->size < SIZE)
	{
		printf("请输入联系人名字:");
		scanf("%s", con->data[con->size].name);
		printf("请输入联系人性别:");
		scanf("%s", con->data[con->size].sex);
		printf("请输入联系人电话:");
		scanf("%s", con->data[con->size].phone);
		printf("请输入联系人地址:");
		scanf("%s", con->data[con->size].location);
		con->size++;
	}
	else
		printf("内存空间不够\n");
}

system(“cls”);清屏函数,在使用前先清下屏,要不之前展示的东西一直放在那,看的不舒服。

if,else语句先判断,我们刚才已经设置好了SIZE,就是通讯录能装的联系人信息的最大值,size是说明当前通讯录里成员的数量。

几个printf,scanf就是把你输入的信息放到struct Contact_Person结构体里。

con->size++;每添加一个联系人,size的大小就增加一个

我们看一下效果:
在这里插入图片描述
在这里插入图片描述

这样我们就已经把信息录入进去了。

4.3显示联系人信息Show_Contact

void Show_Contact(struct Contact* con)
{
	system("cls");
	printf("   %-20s%-8s%-12s%-15s\n", "姓名", "性别", "电话", "地址");
	int i = 0;
	for (i = 0; i < con->size; i++)
	{
		printf("%d. %-20s%-8s%-12s%-15s\n",
		i + 1,
		con->data[i].name,
		con->data[i].sex,
		con->data[i].phone,
		con->data[i].location
		);
	}
}

就是把我们之前录入的练习人信息显示出来。

用for循环实现,总共size个成员所以循环size次。

-20s%,打印字符串并且左对齐20位

我们看效果:(信息我提前添加好了几个,后面用的信息都是这几个)

在这里插入图片描述
在这里插入图片描述

4.3查找联系人Find_Peo

//查找联系人,返回他的序号,如果没有找到返回-1
static int Find_Peo(struct Contact* con, char name[NAME])
{
	int i = 0;
	for (i = 0; i < con->size; i++)
	{
		if (0 == strcmp(con->data[i].name, name))
			return i;
	}
	return -1;
}

这是我们在调用一些函数所用到的函数,比如删除练习人这个函数,我们要找到这个联系人才能删除。所以我们把查找联系人这个函数单独拿出来了,因为在main函数那里用不到这个函数,我们就在前面加上static,把他”保护“起来。其他文件就看不到它,也用不了它了。

我们通过输入联系人的名字来判断它是否存在
所有用for循环,把通讯录里的成员一个一个的对比,如果找到了,就把当前的i值返回出去,也可以理解为把这个成员对应的序列信息返回去了。
如果都遍历完了,就返回-1,说明没找到这个联系人

4.4删除指定联系人信息Delete_Contact

void Delete_Contact(struct Contact* con)
{
	system("cls");
	Show_Contact(con);
	
	printf("请输入需要删除的联系人的姓名:");
	char name[NAME];
	scanf("%s", name);
	int number = 0;
	number = Find_Peo(con, name);
	
	int i = 0;
	if (number != -1)
	{
		for (i = number; i < con->size - 1; i++)
		{
			con->data[i] = con->data[i + 1];
		}
		con->size--;
	}
	else
		printf("找不到联系人\n");
}

在删除之前,先把现有的联系人信息展示出来,这样你就更容易找了。

输入想删除联系人的名字,传到函数Find_Peo里面,返回的值就是这个联系人对应的序号。

我们删除的原理就是,把需要删除的成员被它后面那一个成员的信息覆盖掉。
假设有几个成员1,2,3,4,5.此时我们想删掉2,就把3的信息赋值给2,4赋值给3,5赋值给4。这样就相当于把2删掉啦。

删掉之后记得size–,因为我们通讯录里的成员少了一个

我们看效果:
在这里插入图片描述
删完之后在显示一下
在这里插入图片描述

4.5查找联系人

void Find_Contact(struct Contact* con)
{
	system("cls");
	printf("请输入需要查找的联系人的名字:");
	char name[NAME];
	scanf("%s", name);
	int number = 0;
	number = Find_Peo(con, name);
	if (number != -1)
	{
		printf("%-20s%-8s%-12s%-15s\n", "姓名", "性别", "电话", "地址");
		printf("%-20s%-8s%-12s%-15s\n",
				con->data[number].name,
			    con->data[number].sex,
			    con->data[number].phone,
			    con->data[number].location
		);
	}
	else
		printf("找不到联系人\n");
}

查找也需要用的Find_Peo函数,上面这个查找的代码高级一些,Find_Peo是说明要找的人是否存在,并且返回这个联系人的序号。上面这个函数就是把找到的联系人的信息打印出来

我们看效果:
在这里插入图片描述
在这里插入图片描述
这就找到了,并且展示出来。

4.6修改联系人信息

void Amend_Contact(struct Contact* con)
{
	system("cls");
	Show_Contact(con);
	printf("请输入需要修改联系人信息的名字:");
	char name[NAME];
	scanf("%s", name);
	int number = 0;
	number = Find_Peo(con, name);
	if (number != -1)
	{
		printf("请输入联系人名字:");
		scanf("%s", con->data[number].name);
		printf("请输入联系人性别:");
		scanf("%s", con->data[number].sex);
		printf("请输入联系人电话:");
		scanf("%s", con->data[number].phone);
		printf("请输入联系人地址:");
		scanf("%s", con->data[number].location);
	}
	else
		printf("找不到联系人\n");
}

和删除联系人信息那块代码差别不大
先定位到要修改的联系人的位置,也就是对应的序号,然后重新输入,把之前的信息覆盖掉就行。

我们看效果:
在这里插入图片描述
在这里插入图片描述
修改为在显示一下
在这里插入图片描述

4.7排序联系人信息

static int Com_Name(const void* e1, const void* e2)
{
	return strcmp(((struct Contact_Person*)e1)->name, ((struct Contact_Person*)e2)->name);
}

//排序联系人信息
void Sort_Contact(struct Contact* con)
{
	system("cls");
	qsort(con->data, con->size, sizeof(struct Contact_Person), Com_Name);
	Show_Contact(con);
}

这里主要帮忙让你们学习一些qsort函数的用法

qsort函数

void qsort (void* base, size_t num, size_t size,
int (compar)(const void,const void*));

base:需要排序的数组的地址
num:数组中需要排序的元素个数
size:数组中每个元素的大小(单位是字节)

int (compar)(const void,const void*)

是需要我们自己写的函数,在传参的时候,把我们写的函数的函数名传进去就行.

我们要写的函数,返回值是int,参数是两个const void*类型的
这个函数是用来比较两个元素的大小
如果第一个参数>第二个参数返回大于0的数
如果第一个参数<第二个参数返回大于0的数
如果第一个参数=第二个参数返回等于0的数
具体qsort函数怎么使用这个函数,我们现在可以不用管,如果感兴趣可以看看我的其它文章:指针(二)

在这里我们通过名字来进行排序,就是说数组dat里的成员,按照name来排序。每个成员都是一个结构体,我们使用strcmp函数来判断结构体中name的大小。因为strcmp的返回值和我们需要的返回值是一样的。所以直接返回就行
因为我们比较的两个元素都是结构体,所有先把e1,e2强制类型转换成struct Contact_Person*的类型,然后通过它找到结构体name,最后在进行比较。

我们看结果(为了使效果明显,我加了几个成员)
这是没排序之前:
在这里插入图片描述

排序后:
在这里插入图片描述

按照姓名首字母l<w<z从小到大排好了。

五.代码

想直接用的,复制就行

5.1text.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "contact.h"

void menu()
{
	printf("****************************************\n");
	printf("********  1.添加      2.删除    ********\n");
	printf("********  3.全部删除  4.修改    ********\n");
	printf("********  5.查找      6.显示    ********\n");
	printf("********  7.排序      0.退出    ********\n");
	printf("****************************************\n");
}

int main()
{
	int input = 0;
	struct Contact con;

	//初始化通讯录信息
	Init_Contact(&con);
	do
	{
		menu();
		printf("请输入->");
		scanf("%d", &input);
		switch (input)
		{
		case ADD:
			Add_contact(&con);
			break;
		case DELETE:
			Delete_Contact(&con);
			break;
		case DELETE_ALL:
			Init_Contact(&con);
			break;
		case AMEND:
			Amend_Contact(&con);
			break;
		case FIND:
			Find_Contact(&con);
			break;
		case SHOW:
			Show_Contact(&con);
			break;
		case SORT:
			Sort_Contact(&con);
			break;
		case EXIT:
			break;
		default:
			printf("输入错误,请重新输入->\n");
			break;
		}
	} while (input);
	return 0;
}

5.2contact.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "contact.h"

//初始化通讯录信息
void Init_Contact(struct Contact* con)
{
	con->size = 0;
	memset(con->data, 0, sizeof(con->data));
}

//添加联系人信息
void Add_contact(struct Contact* con)
{
	system("cls");
	if (con->size < SIZE)
	{
		printf("请输入联系人名字:");
		scanf("%s", con->data[con->size].name);
		printf("请输入联系人性别:");
		scanf("%s", con->data[con->size].sex);
		printf("请输入联系人电话:");
		scanf("%s", con->data[con->size].phone);
		printf("请输入联系人地址:");
		scanf("%s", con->data[con->size].location);
		con->size++;
	}
	else
		printf("内存空间不够\n");
}

//显示所有联系人信息
void Show_Contact(struct Contact* con)
{
	system("cls");
	printf("   %-20s%-8s%-12s%-15s\n", "姓名", "性别", "电话", "地址");
	int i = 0;
	for (i = 0; i < con->size; i++)
	{
		printf("%d. %-20s%-8s%-12s%-15s\n",
		i + 1,
		con->data[i].name,
		con->data[i].sex,
		con->data[i].phone,
		con->data[i].location
		);
	}
}

//查找联系人,返回他的序号,如果没有找到返回-1
static int Find_Peo(struct Contact* con, char name[NAME])
{
	int i = 0;
	for (i = 0; i < con->size; i++)
	{
		if (0 == strcmp(con->data[i].name, name))
			return i;
	}
	return -1;
}

//删除指定联系人信息
void Delete_Contact(struct Contact* con)
{
	system("cls");
	Show_Contact(con);
	printf("请输入需要删除的联系人的姓名:");
	char name[NAME];
	scanf("%s", name);
	int number = 0;
	number = Find_Peo(con, name);
	int i = 0;
	if (number != -1)
	{
		for (i = number; i < con->size - 1; i++)
		{
			con->data[i] = con->data[i + 1];
		}
		con->size--;
	}
	else
		printf("找不到联系人\n");
}

//查找联系人
void Find_Contact(struct Contact* con)
{
	system("cls");
	printf("请输入需要查找的联系人的名字:");
	char name[NAME];
	scanf("%s", name);
	int number = 0;
	number = Find_Peo(con, name);
	if (number != -1)
	{
		printf("%-20s%-8s%-12s%-15s\n", "姓名", "性别", "电话", "地址");
		printf("%-20s%-8s%-12s%-15s\n",
				con->data[number].name,
			    con->data[number].sex,
			    con->data[number].phone,
			    con->data[number].location
		);
	}
	else
		printf("找不到联系人\n");
}

//修改联系人信息
void Amend_Contact(struct Contact* con)
{
	system("cls");
	Show_Contact(con);
	printf("请输入需要修改联系人信息的名字:");
	char name[NAME];
	scanf("%s", name);
	int number = 0;
	number = Find_Peo(con, name);
	if (number != -1)
	{
		printf("请输入联系人名字:");
		scanf("%s", con->data[number].name);
		printf("请输入联系人性别:");
		scanf("%s", con->data[number].sex);
		printf("请输入联系人电话:");
		scanf("%s", con->data[number].phone);
		printf("请输入联系人地址:");
		scanf("%s", con->data[number].location);
	}
	else
		printf("找不到联系人\n");
}

static int Com_Name(const void* e1, const void* e2)
{
	return strcmp(((struct Contact_Person*)e1)->name, ((struct Contact_Person*)e2)->name);
}

//排序联系人信息
void Sort_Contact(struct Contact* con)
{
	system("cls");
	qsort(con->data, con->size, sizeof(struct Contact_Person), Com_Name);
	Show_Contact(con);
}

5.3contact.h

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

#define  SIZE      10      //通讯录的大小,能装10个成员的信息
#define  NAME      20      //联系人名字数组的长度
#define  SEX       8       //联系人性别数组的长度
#define  PHONE     12      //联系人电话数组的长度
#define  LOCATION  15      //联系人地址数组的长度


enum catalog
{
	EXIT,      //退出
	ADD,       //添加联系人信息
	DELETE,    //删除联系人信息
	DELETE_ALL,//删除所有人信息
	AMEND,     //修改联系人信息
	FIND,      //查找联系人
	SHOW,      //显示所有联系人信息
	SORT,      //排序联系人信息
};

//联系人信息
struct Contact_Person
{
	char name[NAME];          //联系人姓名
	char sex[SEX];             //联系人性别
	char phone[PHONE];        //联系人电话
	char location[LOCATION];  //联系人地址
};

//通讯录
struct Contact
{
	int size;
	struct Contact_Person data[SIZE];
};

//初始化通讯录信息
void Init_Contact(struct Contact* con);

//添加联系人信息
void Add_contact(struct Contact* con);

//显示所有联系人信息
void Show_Contact(struct Contact* con);

//删除指定联系人信息
void Delete_Contact(struct Contact* con);

//查找联系人
void Find_Contact(struct Contact* con);

//修改联系人信息
void Amend_Contact(struct Contact* con);

//排序联系人信息
void Sort_Contact(struct Contact* con);
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值