C语言-史上最详细的通讯录

通讯录

前言

学结构体学了这么久,终于要用结构体做点东西了。接下来就用结构体的知识实现一个简陋的通讯录。
在这里插入图片描述

项目的文件划分

和之前一样采用模块化的方式创建三个文件即可,一个测试文件text.c,一个contact.c为通讯录的具体实现以及contact.h用来存放实现contact.c的函数声明和类型。

头文件的说明

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

#define MAX 1000
#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_ADDER 30
#define MAX_TELE 15

//类型声明
enum Option
{
    
    
	EXIT,//0
	ADD,//1
	DELETE,//2
	SEARCH,//3
	MODIFY,//4
	SHOW,//5
	SORT//6
};

typedef struct PerInfo {
    
    
	int age;
	char name[MAX_NAME];
	char sex[MAX_SEX];
	char adder [MAX_ADDER];
	char tele[MAX_TELE];
}PerInfo;

typedef struct contact
{
    
    
	PerInfo data[MAX];
	int len;
}contact;

//函数声明
//初始化通讯录
void InitContact(contact* ps);
void AddContact(contact* ps);
void ShowContact(contact* ps);
void DeleteContact(contact *ps);
void SearchContact(contact *ps);
void ModifyContact(contact *ps);
void SortContact(contact* ps)
  1. 用define定义人的基本信息方便后期更改,这样定义可以做到一处修改与之相关的处处修改。
  2. 使用枚举实菜单中数字具有一定的意思,提高代码可读性。

准备工作

1.创建人类

首先通讯录本身可以看做是一个存放数据的容器,而里面的信息就是联系人的具体信息,既然我们要描述一个人的信息,如姓名,年龄,地址等,是用单一的内置类型是无法具体描述的,我们采用结构体这种复杂类型去描述人这个对象,第一步我们将创建一个用来描述人的结构体。

typedef struct PerInfo {
    
    
	int age;
	char name[MAX_NAME];
	char sex[MAX_SEX];
	char adder [MAX_ADDER];
	char tele[MAX_TELE];
}PerInfo;

2.创建通讯录

通讯录里面是不可能存放一个人的信息,它是要具备最基本的增删改查,本身也要具备一定的大小才能去存储信息。所以我们创建一个容量为1000PerInfo的数组的,当我们向里面加入一个人的信息时,我们需要知道通讯录的 容量是否已经达到最值,一旦达到便无法加入信息,由此可知,我们需要一个变量去统计通讯录中的人数。此时我们如果进行增删改查,我们传参的时候即要传联系人的信息和人数,为了减少传参的个数,我们可以将联系人和人数一起放到一个结构体中。该结构体就定义为通讯录。

typedef struct contact
{
    
    
	PerInfo data[MAX];
	int len;
}contact;

3.初始化通讯录

当我们创建好通讯录后需要对通讯录中的数组和变量进行初始化,如果不初始化的话,里面的值都是系统生成的随机值,是无意义的。所以我们将通讯录中的数据都初始化为0,并将这个功能单独定义成一个函数。

void InitContact(contact* ps)
{
    
    
	ps->len = 0;
	memset(ps->data,0,sizeof(ps->data));
}

此时一个空白的数据就创建好了。

通讯录基本功能的实现

1.增加联系人

首先我们要判断通讯录中是否已满,如果已满自然不能加入联系人。如果未满,则添加联系人。我们初始化的时候数组和人数都是0,我们不妨将人数len当做数组的下标来操作,当联系人的信息成功添加len则++。

void AddContact(contact* ps)
{
    
    
	if (ps->len == MAX)
	{
    
    
		printf("通讯录已满,无法添加");
		return;
	}

		printf("请输入您要xxx的基本信息:\n");
		printf("请输入姓名:");
		scanf("%s", ps->data[ps->len].name);
		printf("请输入年龄:");
		scanf("%d", &(ps->data[ps->len].age));
		printf("请输入性别:");
		scanf("%s", ps->data[ps->len].sex);
		printf("请输入手机号码:");
		scanf("%s", ps->data[ps->len].tele);
		printf("请输入住址:");
		scanf("%s", ps->data[ps->len].adder);
		ps->len++;
		printf("添加成功!\n");
}

2.删除联系人

我们先要先判断通讯录是否为空,为空无法删,否则就删。我们删除的前提是要找到某个联系人,就像我们在微信上拉黑某人的去列表中找他在删他。所以我们现在通讯录不为空的前提下查找某一联系人的姓名,当我们找到的时候就删了它。又因为这个查找联系人的功能我们在后面的功能里面也会使用,所以也将它封装成一个函数,以便后面使用。

int isByName(contact *ps,char  name[])
{
    
    
	for (int i = 0; i < ps->len; i++)
	{
    
    
		if (0 == strcmp(ps->data[i].name, name))
		{
    
    
			return 1;
		}
	}
	return -1;
}

void DeleteContact(contact *ps)
{
    
    
	assert(ps);
	char name[20] = {
    
     0 };
	printf("请输入您要删除的联系人的名字:");
	scanf("%s", name);
	int ret=isByName(ps, name);
	if (ps->len >= 0)
	{
    
    
		printf("通讯录为空,无法删除\n");
		return;
	}

	if (ret == -1)
	{
    
    
		printf("查无此人");
	}
	else 
	{
    
    
		for (int i = 0; i < ps->len - 1; i++)
		{
    
    
			ps->data[i] = ps->data[i + 1];
		}
		ps->len--;
		printf("删除成功!\n");
	}
	
}

3.修改联系人

修改联系人和删除联系人的逻辑基本一致,也是先找后操作。我们采用的是传址调用。所以我们找到人之后再重新说输入一遍新联系人的信息便能更改。

void ModifyContact(contact* ps)
{
    
    
	assert(ps);
	char name[20] = {
    
     0 };
	printf("请输入您要修改的联系人的名字:");
	scanf("%s", name);
	int pos = isByName(ps, name);
	if (pos == -1)
	{
    
    
		printf("查无此人");
	}
	else
	{
    
    
		printf("请输入姓名:");
		scanf("%s", ps->data[pos].name);
		printf("请输入年龄:");
		scanf("%d", &(ps->data[pos].age));
		printf("请输入性别:");
		scanf("%s", ps->data[pos].sex);
		printf("请输入手机号码:");
		scanf("%s", ps->data[pos].tele);
		printf("请输入住址:");
		scanf("%s", ps->data[pos].adder);
		printf("添加修改!\n");
	}
}

4.查找联系人

查找就是在通讯录中去找,找到了将打印该联系人的信息,没有找到则打印查无此人。

void SearchContact(contact* ps)
{
    
    
	assert(ps);
	char name[20] = {
    
     0 };
	printf("请输入您要查找的联系人的名字:");
	scanf("%s", name);
	int pos = isByName(ps, name);

	if (pos == -1)
	{
    
    
		printf("查无此人");
	}
	else
	{
    
    
		printf("%-20s %-5s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "手机号码", "地址");
		printf("%-20s %-5d %-5s %-12s %-30s\n", ps->data[pos].name, ps->data[pos].age
			, ps->data[pos].sex, ps->data[pos].tele, ps->data[ps].adder);
	}
}

5.将联系人按照某种规则排序

我们这里采用的是根据姓名进行排序,也可以按照年龄只需要更改比较规则即可。

int ComparyByName(const void* e1, const void* e2)
{
    
    
	return strcmp((const char*)e1, (const char*)e2);
}

void SortContact(contact* ps) 
{
    
    
	qsort(ps->data, ps->len, sizeof(PerInfo), ComparyByName);
}

6.显示通讯录中的联系人

只需要将通讯录中信息打印出来即可。

void ShowContact(contact* ps)
{
    
    
	assert(ps);
	printf("%-20s %-5s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "手机号码", "地址");
	for (int i = 0; i < ps->len; i++)
	{
    
    
		printf("%-20s %-5d %-5s %-12s %-30s\n", ps->data[i].name, ps->data[i].age
			, ps->data[i].sex, ps->data[i].tele, ps->data[i].adder);
	}
}

通讯录基本的功能实现了,为了界面友好与操作,就为通讯录整个菜单。

7.通讯录菜单界面

void menu()
{
    
    
	printf("**|******************|**\n");
	printf("**|1.Add  2.Delete***|**\n");
	printf("**|3.Seacher 4.Modify|**\n");
	printf("**   |5.Show 6.Sort|  **\n");
	printf("**      |0.Exit|      **\n");
	printf("**********|***|*********\n");
	printf("************|***********\n");
}

我们将菜单具体实现也就是操作通讯录的过程也封装成一个函数。

8.菜单操作

void text()
{
    
    
	int input = 0;
	contact con;
	InitContact(&con);
	do {
    
    
		menu();
		printf("请输入您的选择:");
		scanf("%d", &input);
		switch (input)
		{
    
    
		case ADD:
			AddContact(&con);
			break;
		case DELETE:
			DeleteContact(&con);
			break;
		case SEARCH:
			SearchContact(&con);
			break;
		case MODIFY:
			ModifyContact(&con);
			break;
		case SHOW:
			ShowContact(&con);		
			break;
		case SORT:
			SortContact(&con);
			break;
		case EXIT:
			printf("退出通讯录");
			break;
		default:
			printf("您的选择有误,请重新输入!");
		}
	} while (input);

}

通讯录代码

//contact.h文件用于声明函数和类型
#pragma once
#include<stdio.h>
#include<string.h>
#include<assert.h>

#define MAX 1000
#define MAX_NAME 20
#define MAX_SEX 5
#define MAX_ADDER 30
#define MAX_TELE 15

//类型声明
enum Option
{
    
    
	EXIT,//0
	ADD,//1
	DELETE,//2
	SEARCH,//3
	MODIFY,//4
	SHOW,//5
	SORT//6
};

typedef struct PerInfo {
    
    
	int age;
	char name[MAX_NAME];
	char sex[MAX_SEX];
	char adder [MAX_ADDER];
	char tele[MAX_TELE];
}PerInfo;

typedef struct contact
{
    
    
	PerInfo data[MAX];
	int len;
}contact;

//函数声明
//初始化通讯录
void InitContact(contact* ps);
void AddContact(contact* ps);
void ShowContact(contact* ps);
void DeleteContact(contact *ps);
void SearchContact(contact *ps);
void ModifyContact(contact *ps);
void SortContact(contact* ps);


//contact.c文件 通讯录功能的具体实现
#define _CRT_SECURE_NO_WARNINGS 1
#include "contact.h"
void InitContact(contact* ps)
{
    
    
	ps->len = 0;
	memset(ps->data,0,sizeof(ps->data));
}

void AddContact(contact* ps)
{
    
    
	if (ps->len == MAX)
	{
    
    
		printf("通讯录已满,无法添加");
		return;
	}

		printf("请输入您要xxx的基本信息:\n");
		printf("请输入姓名:");
		scanf("%s", ps->data[ps->len].name);
		printf("请输入年龄:");
		scanf("%d", &(ps->data[ps->len].age));
		printf("请输入性别:");
		scanf("%s", ps->data[ps->len].sex);
		printf("请输入手机号码:");
		scanf("%s", ps->data[ps->len].tele);
		printf("请输入住址:");
		scanf("%s", ps->data[ps->len].adder);
		ps->len++;
		printf("添加成功!\n");
}

void ShowContact(contact* ps)
{
    
    
	assert(ps);
	printf("%-20s %-5s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "手机号码", "地址");
	for (int i = 0; i < ps->len; i++)
	{
    
    
		printf("%-20s %-5d %-5s %-12s %-30s\n", ps->data[i].name, ps->data[i].age
			, ps->data[i].sex, ps->data[i].tele, ps->data[i].adder);
	}

}
int isByName(contact *ps,char  name[])
{
    
    
	for (int i = 0; i < ps->len; i++)
	{
    
    
		if (0 == strcmp(ps->data[i].name, name))
		{
    
    
			return 1;
		}
	}
	return -1;
}

void DeleteContact(contact *ps)
{
    
    
	assert(ps);
	char name[20] = {
    
     0 };
	printf("请输入您要删除的联系人的名字:");
	scanf("%s", name);
	int ret=isByName(ps, name);
	if (ps->len >= 0)
	{
    
    
		printf("通讯录为空,无法删除\n");
		return;
	}

	if (ret == -1)
	{
    
    
		printf("查无此人");
	}
	else 
	{
    
    
		for (int i = 0; i < ps->len - 1; i++)
		{
    
    
			ps->data[i] = ps->data[i + 1];
		}
		ps->len--;
		printf("删除成功!\n");
	}
	
}

void SearchContact(contact* ps)
{
    
    
	assert(ps);
	char name[20] = {
    
     0 };
	printf("请输入您要查找的联系人的名字:");
	scanf("%s", name);
	int pos = isByName(ps, name);

	if (pos == -1)
	{
    
    
		printf("查无此人");
	}
	else
	{
    
    
		printf("%-20s %-5s %-5s %-12s %-30s\n", "姓名", "年龄", "性别", "手机号码", "地址");
		printf("%-20s %-5d %-5s %-12s %-30s\n", ps->data[pos].name, ps->data[pos].age
			, ps->data[pos].sex, ps->data[pos].tele, ps->data[pos].adder);
	}
}

void ModifyContact(contact* ps)
{
    
    
	assert(ps);
	char name[20] = {
    
     0 };
	printf("请输入您要修改的联系人的名字:");
	scanf("%s", name);
	int pos = isByName(ps, name);
	if (pos == -1)
	{
    
    
		printf("查无此人");
	}
	else
	{
    
    
		printf("请输入姓名:");
		scanf("%s", ps->data[pos].name);
		printf("请输入年龄:");
		scanf("%d", &(ps->data[pos].age));
		printf("请输入性别:");
		scanf("%s", ps->data[pos].sex);
		printf("请输入手机号码:");
		scanf("%s", ps->data[pos].tele);
		printf("请输入住址:");
		scanf("%s", ps->data[pos].adder);
		printf("添加修改!\n");
	}
}
int ComparyByName(const void* e1, const void* e2)
{
    
    
	return strcmp((const char*)e1, (const char*)e2);
}

void SortContact(contact* ps) 
{
    
    
	qsort(ps->data, ps->len, sizeof(PerInfo), ComparyByName);
}

//text.c文件 通讯录的启动
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include "contact.h"
void menu()
{
    
    
	printf("**|******************|**\n");
	printf("**|1.Add  2.Delete***|**\n");
	printf("**|3.Seacher 4.Modify|**\n");
	printf("**   |5.Show 6.Sort|  **\n");
	printf("**      |0.Exit|      **\n");
	printf("**********|***|*********\n");
	printf("************|***********\n");
}

void text()
{
    
    
	int input = 0;
	contact con;
	InitContact(&con);
	do {
    
    
		menu();
		printf("请输入您的选择:");
		scanf("%d", &input);
		switch (input)
		{
    
    
		case ADD:
			AddContact(&con);
			break;
		case DELETE:
			DeleteContact(&con);
			break;
		case SEARCH:
			SearchContact(&con);
			break;
		case MODIFY:
			ModifyContact(&con);
			break;
		case SHOW:
			ShowContact(&con);		
			break;
		case SORT:
			SortContact(&con);
			break;
		case EXIT:
			printf("退出通讯录");
			break;
		default:
			printf("您的选择有误,请重新输入!");
		}
	} while (input);

}

int main() 
{
    
    
	text();
	return 0;
}
结束语

以上就是本次分享,希望对大家有帮助吧~。如果看完,跪求三连。
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_60308100/article/details/123780047