简单通讯录的实现

本文主要展示简要通讯录的实现


主题框架

首先,我们要有一个主体框架,就是显示对于通讯录的各种操作:增添、删去、查找、修正、排序、退出。代码如下

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");
	printf("***************************\n");
	printf("***************************\n");
	printf("***************************\n");
}

int main()
{
	int input = 0;

	do
	{
		menu();
		printf("请选择:>");
		scanf("%d",&input);
		switch (input)//枚举体里已经定义好每个单词对应的数字,因此单词可以替代数字,同时也提高了代码的可读性
		{
		case ADD:
			break;
		case DEL:
			break;
		case SEARCH:
			break;
		case MODIFY:
			break;
		case SHOW:
			break;
		case SORT:
			break;
		case EXIT:
			break;
		default:
			printf("选择错误");
			break;
		}
	} while (input);
	return 0;
}

这时候,我们该用什么来存储个人的多个信息?----->结构体

我们可以简单地设定两个结构体,

#define MAX 100
#define MAX_NAME 20
#define MAX_SEX 5
#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 sz;//记录通讯录中的有效信息的个数
}Contact,*pContact;

Contact con; //此处声明con这个结构体

 接着,我们先实现往通讯录里增加信息,

这里定义一个函数--AddContact

//将结构体的地址传入函数,会比直接传入一整个结构体更省空间,效率更高
//传入地址,就用指针来接收
void AddContact(Contact* pc);//声明

void AddContact(Contact* pc)//定义
{
	if (pc->sz == MAX)//pc指向的sz,实则就是当前通讯录里的信息数
	{
		printf("通讯录已满,无法增加");
		return;
	}
	printf("请输入名字:>");
	scanf("%s", pc->data[pc->sz].name);

	//pc->data 代表的是在结构体里找到data这个成员变量
	//且data是个数组,故要确定其占的位数,故有pc->sz
	//随后已经进入到data里的第一个元素,也就是第一个结构体,再指向name这个成员变量
	printf("请输入年龄:>");
	scanf("%d", &(pc->data[pc->sz].age));//给年龄赋值
	//此处的pc->sz,是指的是第几号信息
    printf("请输入性别:>");
	scanf("%s", pc->data[pc->sz].sex);//数组不需要取地址
	printf("请输入电话号码:>");
	scanf("%s", pc->data[pc->sz].tele);//数组不需要取地址
	printf("请输入地址:>");
	scanf("%s", pc->data[pc->sz].addr);//数组不需要取地址

	pc->sz++;//记录后+1,为下一个信息留空间
	printf("添加成功");

}

此处的重点,其实是如何用结构体表示我们需要的那个信息

pc->sz  其实是Contact结构体里的sz,sz保存的是当前通讯录中信息的个数

pc->data[pc->sz].()  这里的pc指向的是Contact数组里的data数组,而data数组里又存放着PeoInfo这个结构体的的成员变量

接下来展示删除功能的代码---根据姓名删除相关信息,且后边的数据要往前补齐,那么就需要两个函数1.通过名字查找 。  2.进行删除操作

static int FindByName(const Contact *pc, char name[])//const 修饰指针
{
	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);

void DelContact(Contact* pc)
{
	char name[MAX_NAME] = { 0 };
	if (pc->sz == 0)
	{
		printf("已无更多信息!无法删除");
		return;
	}
	//删除
	//找到要删除的人-位置
	printf("输入要删除的名字:>");
	scanf("%s", name);
	int i = 0;
	int pos = FindByName(pc, name); //pos就是记录要被删除元素的位置,从此位置开始,后往前补齐
	if (pos == -1)
	{
		printf("要删除的人不存在");
		return;//直接返回,结束这个函数的执行
	}
	for (i = pos; i < pc->sz - 1; i++)
	{
		pc->data[i] = pc->data[i + 1];
	}
	pc->sz--;//数据量减少,那么sz也需要减少,可以容纳更多的信息
	printf("删除成功\n");
}

查找函数

void SearchContact(Contact* pc);

void SearchContact(const Contact* pc)
{
	char name[MAX_NAME] = { 0 };
	printf("请输入你要查找的名字:>");
	scanf("%s", name);
	int pos = FindByName(pc, name);
	if (pos == -1)
	{
		printf("要查找的人不存在\n");
		return;//找不到人就结束
	}
	//打印
	printf("%-10s %-4s %5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "地址");
		printf("%-10s %-4d %-5s %-12s %-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)

void ModifyContact(Contact* pc)
{
	char name[MAX_NAME] = { 0 };
	printf("请输入要修改的人的名字");
	scanf("%s", name);
	int pos = FindByName(pc, name);
	if (pos == -1)
	{
		printf("要修改的人不存在");
		return;
	}
	//存在后进行修改
	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);
	//pos存储着要修改的人的位置信息
	//针对当前的位置的信息进行修改

	printf("修改成功\n");
}

排序函数,这里我们需要用到qsort函数,并且自定义一个按照名字,从低到高的函数

//假设按照名字来排序
cmp_by_name(const void* e1, const void* e2)
//传入的指针位置是无类型的
//所以用PeoInfo*来修饰 代表元素是这个结构体里的
{
	return strcmp(((PeoInfo*)e1)->name, ((PeoInfo * )e2)->name); 
}

//qsort默认从低到高排序
void SortContact(Contact* pc)
{
	qsort(pc->data,pc->sz,sizeof(PeoInfo),cmp_by_name);
	printf("排序成功!");
}

除此之外,我们还有一个展示函数,要将当前通讯录里的信息展示出来

void ShowContact(const Contact* pc);

void ShowContact(const Contact* pc)
{
	int i = 0;
	//姓名    年龄    性别   电话     地址
	//zhangsan   20   ...
	printf("%-10s %-4s %5s %-12s %-30s\n", "姓名", "年龄", "性别", "电话", "地址");
	//打印数据
	for (i = 0; i < pc->sz; i++)
	{
		printf("%-10s %-4d %-5s %-12s %-30s\n",
			pc->data[i].name, pc->data[i].age, pc->data[i].sex, pc->data[i].tele, pc->data[i].addr);
	}
}

初始化函数

void InitContact(Contact* pc)//仅是临时拷贝,改变这里的对主函数里的结构体没有任何改变
//所以应该用指针,且传入的应该是地址
{
	pc->sz = 0;
    //信息数置为0
	//pc->data = 0;//数组不能赋值为0,是一个整体
	
    memset(pc->data, 0, sizeof(pc->data)); //这里用memset函数
    //memset(对象,存放内容,存放大小(个数))
}

接着,按照需要,在主函数里引用各个实现定义好的函数即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Nick-An

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值