栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

通讯录(C语言 静态版本)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

通讯录(C语言 静态版本)

通讯录的主要功能:

  1. 增加联系人
  2. 删除联系人
  3. 查找联系人
  4. 排序联系人
  5. 修改联系人
  6. 显示所有联系人
  7. 清空所有联系人
  8. 退出

接下来让我们来看看怎么实现的吧!

1、初始化通讯录 1.1定义结构体

联系人的信息应该包括 姓名、性别、电话、地址,这是多个类型复合在一起,因此我们应该用一个结构体来定义联系人(typedef只是把struct perinfo 重命名成perinfo,让名字更简单好记一点)

typedef struct perinfo
{
	char name[20];//姓名
	char sex[3];
	char number[12];//电话
	char address[20];//地址
}perinfo;

为了方便修改以上数组的容量,我们定义几个符号常量 

#define name_max 20
#define number_max 12
#define address_max 20
#define sex_max 3
typedef struct perinfo
{
	char name[name_max];//姓名
	//char sex;//女为f,男为m
	char sex[sex_max];
	char number[number_max];//电话
	char address[address_max];//地址
}perinfo;

通讯录中不仅有联系人的信息,也应该有通讯录的人数,所以我们再用一个结构体存放联系人的信息和联系人的个数。

typedef struct contact
{
	perinfo member[1000];
	int sz;//记录当前通讯录中已有的人数
}contact;

为了方便修改通讯录可以存放人数的容量,我们定义一个负号常量

#define Max 1000
typedef struct contact
{
	perinfo member[Max];
	int sz;//记录当前通讯录中已有的人数
}contact;
1.2 初始化结构体

初始化结构体的目的:把member数组里的内容初始化为0,sz置为0

//初始化结构体
void Initcontact(contact* pcaller)
{
	assert(pcaller);  //防止pcaller为NULL指针
	pcaller->sz = 0;
	memset(pcaller, 0, sizeof(pcaller->member));  //按字节改变
}
2、通讯录主要功能的实现 2.1 增加联系人
//添加联系人
void Addcontact(contact* pcaller)
{
	if (pcaller->sz == Max)
	{
		printf("通讯录已满,添加失败!n");
		return;
	}
	printf("请输入您所添加联系人的姓名:");
	scanf("%s", pcaller->member[pcaller->sz].name);  //member[ pcaller->sz ]注意括号里所写的
	printf("请输入您所添加联系人的性别:");
	scanf("%s", pcaller->member[pcaller->sz].sex);
	printf("请输入您所添加联系人的电话:");
	scanf("%s", pcaller->member[pcaller->sz].number);
	printf("请输入您所添加联系人的住址:");
	scanf("%s", pcaller->member[pcaller->sz].address);
	pcaller->sz++;
	printf("添加成功n");
}
2.2 打印联系人

打印通讯录中所有人的信息

//打印联系人
void Printcontact(contact* pcaller)
{
	int i;
	printf("%-10s  %-6s %-12s %-20sn", "姓名", "性别", "手机号", "住址");
	for (i = 0; i < (pcaller->sz); i++)
	{
		printf("%-10s  %-6s %-12s %-20sn", pcaller->member[i].name, pcaller->member[i].sex, pcaller->member[i].number, pcaller->member[i].address);
        //%10s 是右对齐,%-10s 是左对齐
	}
	printf("目前有 %d 个联系人n", pcaller->sz);
}
2.3 删除联系人
//删除指定联系人
void Delcontact(contact* pcaller, char *name)
{
	assert(pcaller&&name);
	for (int i = 0; i < pcaller->sz; i++)
	{
		if (strcmp(pcaller->member[i].name, name) == 0)  //字符串与字符串的比较需要用strcmp
		{
			for (int j = i; j < pcaller->sz - 1; j++)
			{
				pcaller->member[j] = pcaller->member[j + 1];
				//memmove(&(pcaller->member[j]), &(pcaller->member[j + 1]), sizeof(pcaller->member[j]));
				(pcaller->sz)--;  //此时通讯录里面的人数减少了一个
				printf("删除成功!!n");
			}
		}
		Printcontact(pcaller);
		return;
	}
	printf("查无此人n");
}

删除指定联系人的原理就是,把该联系人的信息用后一个联系人的信息覆盖住,从该联该系人后一个联系人开始,全部往前挪一个位置。

至于如何覆盖,有两种方式

  1. 直接赋值  member[j]=member[j+1];
  2. 用memmove函数  memmove(&(pcaller->member[j]), &(pcaller->member[j + 1]), sizeof(pcaller->member[j]));
 2.4  查找联系人

根据输入的联系人的姓名来找到联系人的信息并打印出来。

//查找联系人
void Searchcontact(contact* pcaller, char *name)
{
	assert(pcaller&&name);
	for (int i = 0; i < pcaller->sz; i++)
	{
		if (strcmp(pcaller->member[i].name, name) == 0)
		{
			printf("%-10s  %-6s %-12s %-20sn", "姓名", "性别", "手机号", "住址");
			printf("%-10s  %-6s %-12s %-20sn", pcaller->member[i].name, pcaller->member[i].sex, pcaller->member[i].number, pcaller->member[i].address);
		}
		return;
	}
	printf("查无此人n");
}
2.5 修改联系人
//修改联系人
void Modifycontact(contact* pcaller, char* name)
{
	assert(pcaller&&name);
	for (int i = 0; i < pcaller->sz; i++)
	{
		if (strcmp(pcaller->member[i].name, name) == 0)
		{
			printf("请输入您所修改联系人的姓名:");
			scanf("%s", pcaller->member[i].name);
			printf("请输入您所修改联系人的性别:");
			scanf("%s", pcaller->member[i].sex);
			printf("请输入您所修改联系人的电话:");
			scanf("%s", pcaller->member[i].number);
			printf("请输入您所修改联系人的住址:");
			scanf("%s", pcaller->member[i].address);
			printf("修改成功n");
		}
		return;
	}
	printf("查无此人n");
}
2.6 排序联系人

根据姓名排序联系人,我们可以用qsort函数实现快排,为了使用qsort函数我们还要写一个比较函数。

//排序联系人(按姓名排序)
int compare_name(const perinfo* e1, const perinfo* e2)
{
	return strcmp(e1->name, e2->name);
}
void Sortcontact(contact* pcaller)
{
	qsort(pcaller->member, pcaller->sz, sizeof(pcaller->member[0]), compare_name);
	Printcontact(pcaller);
}
2.7 清空所有联系人

清空所有联系人,也就是相当于给通讯录重新初始化一次

//清空所有联系人
void Empty_contact(contact*pcaller)
{
	Initcontact(pcaller);
	printf("清空成功n");
}
3.一些小细节上的处理
enum select
{
	exit0,
	add,
	del,
	search,
	print,
	modify,
	sort,
	empty
};

void menu()
{
	int op = 0;
	contact caller;
	//初始化结构体
	Initcontact(&caller);
	do
	{
		printf("********     欢迎使用通讯录     ********************n");
		printf("****1、增加联系人*******2、删除联系人*********n");
		printf("****3、查找联系人*******4、显示所有联系人****n");
		printf("****5、修改联系人*******6、排序联系人********n");
		printf("****7、清空所有联系人**0、退出*************n");
		printf("***************************************************n");
		printf("请输入你的选择:>");
		scanf("%d", &op);
		switch (op)
		{
		case add:
			Addcontact(&caller);
			break;

		case del:
			printf("请输入你想删除的联系人的姓名:");
			char name[20];
			scanf("%s", name);
			Delcontact(&caller, name);
			break;

		case search:
			printf("请输入你想查找的联系人的姓名:");
			char name1[20];
			scanf("%s", name1);
			Searchcontact(&caller, name1);
			break;

		case print:
			Printcontact(&caller);
			break;

		case modify:
			printf("请输入你想删除的联系人的姓名:");
			char name2[20];
			scanf("%s", name2);
			Modifycontact(&caller, name2);
			break;

		case sort:
			Sortcontact(&caller);
			break;

		case empty:
			Empty_contact(&caller);

		case exit0:
			printf("您已退出!");
			break;

		default:
			printf("输入错误,请重新输入");
		}
	} while (op);
}

在menu函数中我们使用了枚举常量,为什么要这样呢?

  1. 枚举常量本身没有实际意义,但是能提高我们的可读性,其名字可以很好的体现要实现什么功能。
  2. 系统会为枚举常量赋予初值,我们可以利用这个代替op
4.整体代码

我们将代码分到三个文件中,一个工程是需要由一个头文件,两个源文件组成的。

Contact.h 为头文件,用于放结构体的声明,符号常量的定义,函数的声明。

#pragma once
#include
#include
#include
#include
#define Max 1000
#define name_max 20
#define number_max 12
#define address_max 20
#define sex_max 3
enum select
{
	exit0,
	add,
	del,
	search,
	print,
	modify,
	sort,
	empty
};
typedef struct perinfo
{
	char name[name_max];//姓名
	//char sex;//女为f,男为m
	char sex[sex_max];
	char number[number_max];//电话
	char address[address_max];//地址
}perinfo;
typedef struct contact
{
	perinfo member[Max];
	int sz;//记录当前通讯录中已有的人数
}contact;
void Initcontact(contact* pcaller);
void Addcontact(contact* pcaller);
void Printcontact(contact* pcaller);
void Delcontact(contact* pcaller, char* name);
void Searchcontact(contact* pcaller, char* name);
void Modifycontact(contact* pcaller, char* name);
void Sortcontact(contact* pcaller);
void Empty_contact(contact*pcaller);

Contact.c为源文件,存放函数实现的代码,封装函数。连接Contact.c和Contact.h只需要用#include“Contact.h”就可以了;

注意:自己写的头文件用 “ ” 引用。

#include"contact.h"

//初始化结构体
void Initcontact(contact* pcaller)
{
	assert(pcaller);
	pcaller->sz = 0;
	memset(pcaller, 0, sizeof(pcaller->member));
}

//添加联系人
void Addcontact(contact* pcaller)
{
	if (pcaller->sz == Max)
	{
		printf("通讯录已满,添加失败!n");
		return;
	}
	printf("请输入您所添加联系人的姓名:");
	scanf("%s", pcaller->member[pcaller->sz].name);  //member[ pcaller->sz ]注意括号里所写的
	//char c;
	//while (c = getchar() != 'n')
	//{

	//}          //由于性别我们只定义了一个字符,在之前我们输入联系人姓名时,会按下回车键,如果不用循环把'n'去掉,就会把'n'给sex
	printf("请输入您所添加联系人的性别:");
	//scanf("%c", &(pcaller->member[pcaller->sz].sex));
	scanf("%s", pcaller->member[pcaller->sz].sex);
	printf("请输入您所添加联系人的电话:");
	scanf("%s", pcaller->member[pcaller->sz].number);
	printf("请输入您所添加联系人的住址:");
	scanf("%s", pcaller->member[pcaller->sz].address);
	pcaller->sz++;
	printf("添加成功n");
}

//打印联系人
void Printcontact(contact* pcaller)
{
	int i;
	printf("%-10s  %-6s %-12s %-20sn", "姓名", "性别", "手机号", "住址");
	for (i = 0; i < (pcaller->sz); i++)
	{
		printf("%-10s  %-6s %-12s %-20sn", pcaller->member[i].name, pcaller->member[i].sex, pcaller->member[i].number, pcaller->member[i].address);
	}
	printf("目前有 %d 个联系人n", pcaller->sz);
}

//删除联系人
void Delcontact(contact* pcaller, char *name)
{
	assert(pcaller&&name);
	for (int i = 0; i < pcaller->sz; i++)
	{
		if (strcmp(pcaller->member[i].name, name) == 0)
		{
			for (int j = i; j < pcaller->sz - 1; j++)
			{
				pcaller->member[j] = pcaller->member[j + 1];
				//memmove(&(pcaller->member[j]), &(pcaller->member[j + 1]), sizeof(pcaller->member[j]));
				(pcaller->sz)--;
				printf("删除成功!!n");
			}
		}
		Printcontact(pcaller);
		return;
	}
	printf("查无此人n");
}

//查找联系人
void Searchcontact(contact* pcaller, char *name)
{
	assert(pcaller&&name);
	for (int i = 0; i < pcaller->sz; i++)
	{
		if (strcmp(pcaller->member[i].name, name) == 0)
		{
			printf("%-10s  %-6s %-12s %-20sn", "姓名", "性别", "手机号", "住址");
			printf("%-10s  %-6s %-12s %-20sn", pcaller->member[i].name, pcaller->member[i].sex, pcaller->member[i].number, pcaller->member[i].address);
		}
		return;
	}
	printf("查无此人n");
}

//修改联系人
void Modifycontact(contact* pcaller, char* name)
{
	assert(pcaller&&name);
	for (int i = 0; i < pcaller->sz; i++)
	{
		if (strcmp(pcaller->member[i].name, name) == 0)
		{
			printf("请输入您所修改联系人的姓名:");
			scanf("%s", pcaller->member[i].name);
			printf("请输入您所修改联系人的性别:");
			scanf("%s", pcaller->member[i].sex);
			printf("请输入您所修改联系人的电话:");
			scanf("%s", pcaller->member[i].number);
			printf("请输入您所修改联系人的住址:");
			scanf("%s", pcaller->member[i].address);
			printf("修改成功n");
		}
		return;
	}
	printf("查无此人n");
}


//排序联系人
int compare_name(const perinfo* e1, const perinfo* e2)
{
	return strcmp(e1->name, e2->name);
}
void Sortcontact(contact* pcaller)
{
	qsort(pcaller->member, pcaller->sz, sizeof(pcaller->member[0]), compare_name);
	Printcontact(pcaller);
}

//清空所有联系人
void Empty_contact(contact*pcaller)
{
	Initcontact(pcaller);
	printf("清空成功n");
}

test.c 为源文件,用于测试通讯录的功能

#include"contact.h"
void menu()
{
	int op = 0;
	contact caller;
	//初始化结构体
	Initcontact(&caller);
	do
	{
		printf("********     欢迎使用通讯录     ********************n");
		printf("****1、增加联系人*******2、删除联系人*********n");
		printf("****3、查找联系人*******4、显示所有联系人****n");
		printf("****5、修改联系人*******6、排序联系人********n");
		printf("****7、清空所有联系人**0、退出*************n");
		printf("***************************************************n");
		printf("请输入你的选择:>");
		scanf("%d", &op);
		switch (op)
		{
		case add:
			Addcontact(&caller);
			break;

		case del:
			printf("请输入你想删除的联系人的姓名:");
			char name[20];
			scanf("%s", name);
			Delcontact(&caller, name);
			break;

		case search:
			printf("请输入你想查找的联系人的姓名:");
			char name1[20];
			scanf("%s", name1);
			Searchcontact(&caller, name1);
			break;

		case print:
			Printcontact(&caller);
			break;

		case modify:
			printf("请输入你想删除的联系人的姓名:");
			char name2[20];
			scanf("%s", name2);
			Modifycontact(&caller, name2);
			break;

		case sort:
			Sortcontact(&caller);
			break;

		case empty:
			Empty_contact(&caller);

		case exit0:
			printf("您已退出!");
			break;

		default:
			printf("输入错误,请重新输入");
		}
	} while (op);
}
int main()
{
	menu();
    return 0;
}

写了一个通讯录的代码并不只是一个通讯录的代码,平时学校要求做的C语言或者C++的课题,项目,大作业,如:图书管理系统,诊所管理系统等等。这些都是差不多的实现方式,学会通讯录就可以解锁其它大同小异的问题。

通讯录就这样写完了,后面我还会介绍动态增长版本的通讯录以及用文件操作通讯录,bye~

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/867280.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号