用C语言实现初阶通讯录(静态版本)

主体的构建

各位读者好,当我们学习过了结构体,枚举的时候,我们就可以用之前所学过的知识来完成一个通讯录的实现,当然这只是一个静态版本的通讯录,在后续的文章中我会依次发布通讯录的中阶版本(动态版本),高阶版本(文件版本)
那么就让我们来一步一步的慢慢实现吧!
首先,我们可以先搭建起我们通讯录的主体。因为我们所使用的通讯录应该有,增加联系人,删减联系人,修改联系人,显示联系人等等目的,所以我们就根据这些来搭建我们的主体框架
同我之前的文章里实现扫雷一样,我们先创建两个.c文件,一个.h文件,如下图
在这里插入图片描述
然后我们在Contact.h文件中先定义两个结构体,一个是包含具体的联系人信息的结构体,另一个是实现整个通讯录的结构体,如下图代码

#include<stdio.h>
#define NAME_MAX 10
#define SEX_MAX 4
#define ADDR_MAX 20
#define TELE_MAX 11
#define MAX 100

struct Peo
{
    
    
	char name[NAME_MAX];//定义一个字符串来储存名字
	char sex[SEX_MAX];//定义一个字符串来存储性别
	int age;//定义一个整形用来存储年龄
	char addr[ADDR_MAX];//定义一个字符串来存储联系人的地址
	char tele[TELE_MAX];//定义一个字符串来存储联系人的地址
};
struct Contact
{
    
    
	struct Peo  Con[MAX];//定义一个结构体数组用来储存每个联系人的信息
	int sz;//用来储存通讯录中的人数
};

当在Contact.h文件中我们定义了之后,我们就可以在main.c文件中构建我们大概的框架了,具体看下面代码

#define  _CRT_SECURE_NO_WARNINGS	
#include "Contact.h"

void menu()
{
    
    
	printf("*****************************\n");
	printf("****  1.Add   2.Sub     *****\n");
	printf("****  3.Mod   4.Show    *****\n");
	printf("****  5.Init  0.Exit    *****\n");
	printf("*****************************\n");
}
enum input
{
    
    
	Exit,//对应的值是0
	Add,//对应的值是1,依次往下类推
	Sub,
	Mod,
	Show,
	Init
};
int main()
{
    
    
	int input = 1;
	struct Contact CON;
	while(input)//只有当input为0时才能推出循环
	{
    
    
		menu();//写一个菜单函数
	    scanf("%d", &input);		
		switch (input)
		{
    
    
		case Add:
			AddNumber(&CON);//增加函数
			break;
		case Sub:
			SubNumber(&CON);//删减函数
			break;
		case Mod:
			ModNumber(&CON);//修改函数
			break;
		case Show:
			ShowNumber(&CON);//展示函数
			break;
		case Init:
			InitNumber(&CON);//初始化通讯录函数
			break;
		case Exit:
			printf("退出通讯录\n");
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
	    }
	
	}
}

当我们搭起框架以后就可以去Contact.c文件中具体实现每一个函数了,别忘了实现完一个每一个函数的时候要去Contact.h中声名函数

功能函数的实现

展示函数的实现

我建议你先实现这一个函数,因为,这样你就能很好的用这个函数去检验你增加函数等等有没有写对。具体代码如下图

void ShowNumber(struct Contact *CON)
{
    
    
	if (CON->sz == 0)
	{
    
    
		printf("通讯录为空\n");//判断一下啊,如果通讯录为空,那么将无法显示
		return;

	}
	else
	{
    
    
		int i = 0;
		printf("%s\t%s\t%s\t%s\t%s\n","姓名","年龄","性别","地址","电话");
		for (; i < CON->sz; i++)
		{
    
    
			printf("%s\t%-d\t%s\t%s\t%s\n", 
				(CON->Con + i)->name, 
				(CON->Con + i)->age,
				(CON->Con + i)->sex,
				(CON->Con + i)->addr,
				(CON->Con + i)->tele);
		}
	}
}

增加函数的实现

增加函数,简而言之就是往里面存储联系人的信息,同时储存数sz要++;要注意在下面的函数中我们都会用到sz这个变量,因为我们可以根据通讯录中存储的人数来找到储存最后一名联系人信息的地址,具体看下图代码吧!

void AddNumber(struct Contact *CON)
{
    
    
	if (CON->sz == MAX)
	{
    
    
		printf("通讯录已满,请先删除联系人\n");//先判断一下通讯录是否已经存满
		return;
	}
	else
	{
    
    
		printf("请输入联系人的名字\n");
		scanf("%s",(CON->Con+CON->sz)->name);
		printf("请输入联系人的性别\n");
		scanf("%s", (CON->Con + CON->sz)->sex);
		printf("请输入联系人的年龄\n");
		scanf("%d", &((CON->Con + CON->sz)->age));//要注意,这里要加&符号,因为其他成员变量都是字符串,相当于数组名就是地址,所以其他几个不用加。
		printf("请输入联系人的地址\n");
		scanf("%s", (CON->Con + CON->sz)->addr);
		printf("请输入联系人的电话\n");
		scanf("%s", (CON->Con + CON->sz)->tele);
		++(CON->sz);//添加了之后别忘了自增 sz。
	}

}

删减函数的实现

大体思路就是先检查一下通讯录是否为空,然后定义一个字符串用来存储想要删除的名字,并循环遍历比较,如果相同,那么就用第 i+1 个结构体来覆盖第 i 个结构体。

void SubNumber(struct Contact *CON)
{
    
    
	if (CON->sz == 0)
	{
    
    
		printf("通讯录为空,无法删除\n");
		return;

	}
	else
	{
    
    
		char name[NAME_MAX];
		printf("请输入你想删除的联系人的名字\n");
		scanf("%s",name);
		int i = 0;
		if (CON->sz == 1)
		{
    
    
			if (strcmp(name, (CON->Con->name)) == 0)
			{
    
    
				memset(CON->Con, 0, sizeof(struct Peo));
				printf("删除成功\n");
				--(CON->sz);
				return;
			}
			else
			{
    
    
				printf("通讯录中无此人\n");
				return;
			}
		}//因为只有一个联系人的时候,对于后面循环遍历覆盖有点特殊,我们可以选择特殊处理	
		for (i = 0 ; i < CON->sz; i++)
		{
    
    
			if (strcmp(name, (CON->Con + i)->name) == 0)
			{
    
    
				i += 1;
				for (; i < CON->sz;i++)
				{
    
    

					(CON->Con)[i-1] = (CON->Con)[i];//可以直接将相同类型的结构体进行赋值操作
				}
				printf("删除成功\n");
				--(CON->sz);
				return;
			}

		}
		printf("通讯录中无此人,无法删除\n");
		return;

	}
}

修改函数的实现

修改函数和删减函数差不多,只需要找到后更改就行,代码如下图

void ModNumber(struct Contact *CON)
{
    
    
	if (CON->sz == 0)
	{
    
    
		printf("通讯录为空,无法修改\n");
		return;

	}
	else
	{
    
    
		char name[NAME_MAX];
		printf("请输入你想修改的联系人的名字\n");
		scanf("%s", name);
		int i = 0;
		for (; i < CON->sz; i++)
		{
    
    
			if (strcmp(name, (CON->Con + i)->name) == 0)
			{
    
    
				printf("请输入联系人的名字\n");
				scanf("%s", (CON->Con + i)->name);
				printf("请输入联系人的性别\n");
				scanf("%s", (CON->Con + i)->sex);
				printf("请输入联系人的年龄\n");
				scanf("%d", &((CON->Con + i)->age));
				printf("请输入联系人的地址\n");
				scanf("%s", (CON->Con + i)->addr);
				printf("请输入联系人的电话\n");
				scanf("%s", (CON->Con + i)->tele);
			    printf("修改成功\n");
			    return;
			}			
		}
		printf("通讯录中无此人\n");
		return;
	}
}

初始化函数

初始化函数的我们可以使用memset这个函数来帮忙实现,具体代码如下图

void InitNumber(struct Contact *CON)
{
    
    
	if (CON->sz == 0)
	{
    
    
		printf("通讯录为空,无需初始化\n");
		return;

	}
	else
	{
    
    
		memset(CON->Con, 0, MAX*sizeof(struct Peo));
		//第一个参数为地址,第二个参数为要设置的字符的ASCII码值,第三个参数为要设置的字节数
		CON->sz = 0;
		printf("初始化成功\n");
        return;
	}

}

代码和程序一览

到这,我们大概就能初步实现以大概实现静态版本的通讯录了,下面附上几张代码一览图和运行图
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
希望这对看到文章的你有帮助,再见!感谢阅读

猜你喜欢

转载自blog.csdn.net/weixin_51306225/article/details/115050497