手把手教你写通讯录【C语言版】

欢迎光临

各位大帅哥,大美女
如果觉得文章对自己有帮助
可以一键三连支持博主哦

你们的支持都是我坚持的动力 手把手教你写通讯录【C语言版】_第1张图片

 前言

建议:我们可以分模块,我这里就分了三个模块,test.c用于专门测试通讯录功能,contact.c和contact.h用于接口的实现和接口的声明

一个简单的通讯录可以用来:

存储1000个人的信息

每个人的基本信息主要是:姓名、电话、年龄、地址、性别……

如果你想要添加别的信息也可以。

通讯录功能:

1、添加联系人

2、查找联系人

3、删除联系人

4、查看所有联系人

5、修改联系人信息

6、按名字排序

相关的函数接口 

//初始化通讯录
void Initcontact(contact* pa);

//增加联系人的信息
void Addcontact(contact* pa);

//删除指定联系人的信息
void Delcontact(contact* pa);

//打印通讯录中的信息
void Printcontact(contact* pa);

//查找指定联系人信息
void Searchcontact(const contact* pa);

//按字典顺序排序
void Sortcontact(contact* pa);

//修改指定联系人的信息
void Modifycontact(contact* pa);

//销毁通讯录
void Destroycontact(contact* pa);

  目录

1、定义联系人信息和通讯录

  • 定义联系人信息
  • 定义通讯录内容

2、设计通讯录目录

3、通讯录主函数

4、初始化通讯录

5、打印所有联系人

6、添加联系人

7、删除联系人

8、查找联系人

9、按字母顺序排序通讯录

10、头文件

11、完整代码(附有动态版本和文件版本)


1、定义联系人信息和通讯录

 1.1定义联系人信息

这里就要用到结构体了,结构体不熟的要去补补喽。

为了以后方便改数值,我们可以用#define全局变量声明一下。

代码如下:

#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 12
#define ADDR_MAX 30
typedef struct peoinfo
{
	char name[NAME_MAX];
	char sex[SEX_MAX];
	int age;
	char tele[TELE_MAX];
	char addr[ADDR_MAX];
} peoinfo;

1.2定义通讯录的内容

 代码如下:

#define MAX 1000
typedef struct contact
{
	peoinfo data[MAX];//通讯录容量
	int sz;//记录通讯录中已经存放的信息个数
} contact;

2、设计通讯录目录:

首先我们要设计一个目录,目录的话很简单,可以根据自己喜欢设计,这里就不多说,代码如下:

void menu()
{
	printf("****************************\n");
	printf("**** 1.增加    2.删除   ****\n");
	printf("**** 3.查找    4.修改   ****\n");
	printf("**** 5.排序    6.打印   ****\n");
	printf("**** 0.退出             ****\n");
	printf("****************************\n");
}

运行结果如下:

手把手教你写通讯录【C语言版】_第2张图片


3、通讯录主函数

 设计完目录后,我们还要把我们的主函数设计出来

代码如下:

void test()
{
	int input = 0;
	//创建通讯录
	contact con;
	//初始化通讯录
	Initcontact(&con);
	do
	{
		menu();
		printf("请选择功能:>");
		scanf("%d", &input);
		switch (input)
		{
		case ADD:
			Addcontact(&con);
			break;
		case DEL:
			Delcontact(&con);
			break;
		case SEARCH:
			Searchcontact(&con);
			break;
		case MODIFY:
			Modifycontact(&con);
			break;
		case SORT:
			Sortcontact(&con);
			break;
		case PRINT:
			Printcontact(&con);
			break;
		case EXIT:
			Savecontact(&con);
			Destroycontact(&con);
			printf("退出通讯录\n");
			break;
		default:
			printf("选择错误\n");
			break;
		}
	} while (input);
}

int main()
{
	test();
	return 0;
}

对于这些功能我们可以用枚举来达到这样的效果

代码如下:

//枚举
enum Option
{
	EXIT,//退出
	ADD,//增加
	DEL,//删除
	SEARCH,//查找
	MODIFY,//修改
	SORT,//排序
	PRINT//打印
};

4、初始化通讯录

最开始我们的通讯录是一个人也没有,所以我们要把通讯录的内容全都初始化为0,否则是随机值,那我们后面在进行下去也是毫无意义的。

代码如下:

void Initcontact(contact* pa)
{
	pa->sz = 0;//设置通讯录只有0个元素
	memset(pa->data, 0, sizeof(pa->data));//初始化数组
}

5、打印所有联系人

这个是最简单的,有手就行,不多讲。

代码如下:

void Printcontact(contact* pa)
{
	assert(pa);
	int i = 0;
	printf("%-10s %-5s %-5s %-12s %-20s\n", "姓名", "年龄", "性别", "电话", "地址");
	for (i = 0; i < pa->sz; i++)
	{
		printf("%-10s %-5d %-5s %-12s %-20s\n", pa->data[i].name,pa->data[i].age,pa->data[i].sex,pa->data[i].tele,pa->data[i].addr);
	}
}

 6、添加联系人

这里我们一定要注意断言哦!!! 

这里的判断语句也是需要用动态版本进一步升级的地方。

void Addcontact(contact* pa)
{
	assert(pa);
	if (pa->sz == MAX)
	{
		printf("通讯录已满,无法添加\n");
	}
	//录入信息
	printf("请输入名字:>");
	scanf("%s", pa->data[pa->sz].name);
	printf("请输入年龄:>");
	scanf("%d", &pa->data[pa->sz].age);
	printf("请输入性别:>");
	scanf("%s", pa->data[pa->sz].sex);
	printf("请输入电话:>");
	scanf("%s", pa->data[pa->sz].tele);
	printf("请输入地址:>");
	scanf("%s", pa->data[pa->sz].addr);
	pa->sz++;
	printf("添加成功\n");
}

演示结果:

手把手教你写通讯录【C语言版】_第3张图片


  7、 删除联系人

删除联系人分两步,一是先要找到改联系人,二再是删除,还要注意判断一下通讯录是否为空。 

代码如下:

//找到了返回下标
//找不到返回-1
int FindName(const contact* pa, char name[])
{
    assert(pa);
    int i = 0;
    for (i = 0; i < pa->sz; i++)
    {
        if (0 == strcmp(pa->data[i].name, name))
        {
            return i;
        }
    }
    return -1;
}

这里用了一个FindName函数在后面的查找联系人中也用的到。

void Delcontact(contact* pa)
{
	assert(pa);
	if (pa->sz==0)
	{
		printf("通讯录已空\n");
	}
	//1、找到
	char name[NAME_MAX] = { 0 };
	printf("请输入要删除的名字:>");
	scanf("%s", name);
	int pos = FindName(pa, name);
	if (pos == -1)
	{
		printf("要删除的人不存在\n");
		return;
	}
	//2、删除
	int j = 0;
	for (j = pos; j < pa->sz - 1; j++)
	{
		pa->data[j] = pa->data[j + 1];
	}
	pa->sz--;
	printf("删除成功\n");
}

演示效果:

手把手教你写通讯录【C语言版】_第4张图片  


 8、查找联系人

查找联系人我并不需要修改它,所以我们可以用const限定一下。

代码如下:

void Searchcontact(const contact* pa)
{
    char name[NAME_MAX] = { 0 };
    printf("请输入要查找的名字:>");
    scanf("%s", name);
    int pos = FindName(pa, name);
    if (pos == -1)
    {
        printf("要查找的人不存在\n");
        return;
    }
    printf("%-10s %-5s %-5s %-12s %-20s\n", "姓名", "年龄", "性别", "电话", "地址");
    printf("%-10s %-5d %-5s %-12s %-20s\n", pa->data[pos].name, pa->data[pos].age, pa->data[pos].sex, pa->data[pos].tele, pa->data[pos].addr);
}

演示效果:

手把手教你写通讯录【C语言版】_第5张图片


 9、按字母顺序排序通讯录

这里我用的是qsort函数更简单一点,不过要注意qsort函数的参数不要用错了,当然你们也可以用别的,比如冒泡排序也是可行的。

代码如下:

int Cmpname(const void* e1, const void* e2)
{
	return strcmp(((peoinfo*)e1)->name,((peoinfo*)e2)->name);
}
void Sortcontact(contact* pa)
{
	assert(pa);
	qsort(pa->data, pa->sz, sizeof(pa->data[0]), Cmpname);
	printf("排序成功\n");
}

演示效果:

手把手教你写通讯录【C语言版】_第6张图片 

10、头文件 

#include 
#include 
#include 
#include 

11、完整代码(附有动态版本和文件版本)

contact.h

#pragma once

#include 
#include 
#include 
#include 

//类型声明
#define NAME_MAX 20
#define SEX_MAX 5
#define TELE_MAX 12
#define ADDR_MAX 30
#define MAX 1000
//通讯录初始状态的容量大小
#define DEFAULT_SZ 5
//枚举
enum Option
{
	EXIT,
	ADD,
	DEL,
	SEARCH,
	MODIFY,
	SORT,
	PRINT
};

typedef struct peoinfo
{
	char name[NAME_MAX];
	char sex[SEX_MAX];
	int age;
	char tele[TELE_MAX];
	char addr[ADDR_MAX];
} peoinfo;

//静态的版本
//typedef struct contact
//{
//	peoinfo data[MAX];//通讯录容量
//	int sz;//记录通讯录中已经存放的信息个数
//} contact;

//动态的版本
typedef struct contact
{
	peoinfo* data;//可以存放1000个人的信息
	int sz;//记录通讯中已经保存的信息个数
	int capacity;//记录通讯录当前的最大容量
} contact;

//函数声明

//初始化通讯录
void Initcontact(contact* pa);

//增加联系人的信息
void Addcontact(contact* pa);

//删除指定联系人的信息
void Delcontact(contact* pa);

//打印通讯录中的信息
void Printcontact(contact* pa);

//查找指定联系人信息
void Searchcontact(const contact* pa);

//按字典顺序排序
void Sortcontact(contact* pa);

//修改指定联系人的信息
void Modifycontact(contact* pa);

//销毁通讯录
void Destroycontact(contact* pa);

//文件版本
void Savecontact(const contact* pa);

contact.c

#define _CRT_SECURE_NO_WARNINGS 1

#include "contact.h"

//静态的版本
//void Initcontact(contact* pa)
//{
//	pa->sz = 0;
//	memset(pa->data, 0, sizeof(pa->data));//初始化数组
//}

//动态的版本
//void Initcontact(contact* pa)
//{
//	assert(pa);
//	pa->sz = 0;
//	pa->capacity = DEFAULT_SZ;
//	pa->data = (peoinfo*)malloc(pa->capacity * sizeof(peoinfo));
//	if (pa->data == NULL)
//	{
//		perror("Initcontact::malloc");
//		return;
//	}
//	memset(pa->data, 0, pa->capacity * sizeof(peoinfo));//初始化数组
//}

void checkcapacity(contact* pa)//检查容量
{
	if (pa->sz == pa->capacity)
	{
		peoinfo* tmp = (peoinfo*)realloc(pa->data, (pa->capacity + 3) * sizeof(peoinfo));
		if (tmp != NULL)
		{
			pa->data = tmp;
		}
		else
		{
			perror("checkcapacity::realloc");
			return;
		}
		pa->capacity += 3;
		printf("增容成功\n");
	}
}

void Loadcontact(contact* pa)
{
	//打开文件
	FILE* pf = fopen("contact.txt", "rb");
	if (pf == NULL)
	{
		perror("Loadconatct::fopen");
		return;
	}
	//读文件
	peoinfo tmp = { 0 };
	while (fread(&tmp, sizeof(peoinfo), 1, pf))
	{
		checkcapacity(pa);
		pa->data[pa->sz] = tmp;
		pa->sz++;
	}
	//关闭文件
	fclose(pf);
	pf = NULL;
}


//文件版本
void Initcontact(contact* pa)
{
	assert(pa);
	pa->sz = 0;
	pa->capacity = DEFAULT_SZ;
	pa->data = (peoinfo*)malloc(pa->capacity * sizeof(peoinfo));
	if (pa->data == NULL)
	{
		perror("Initcontact::malloc");
		return;
	}
	memset(pa->data, 0, pa->capacity * sizeof(peoinfo));//初始化数组

	//加载文件信息到通讯录中
	Loadcontact(pa);
}


void Addcontact(contact* pa)
{
	assert(pa);
	//静态的版本
	/*if (pa->sz == MAX)
	{
		printf("通讯录已满,无法添加\n");
	}*/
	//录入信息

	//动态的版本
	checkcapacity(pa);

	printf("请输入名字:>");
	scanf("%s", pa->data[pa->sz].name);
	printf("请输入年龄:>");
	scanf("%d", &pa->data[pa->sz].age);
	printf("请输入性别:>");
	scanf("%s", pa->data[pa->sz].sex);
	printf("请输入电话:>");
	scanf("%s", pa->data[pa->sz].tele);
	printf("请输入地址:>");
	scanf("%s", pa->data[pa->sz].addr);
	pa->sz++;
	printf("添加成功\n");
}

//找到了返回下标
//找不到返回-1
int FindName(const contact* pa, char name[])
{
	assert(pa);
	int i = 0;
	for (i = 0; i < pa->sz; i++)
	{
		if (0 == strcmp(pa->data[i].name, name))
		{
			return i;
		}
	}
	return -1;
}
void Delcontact(contact* pa)
{
	assert(pa);
	if (pa->sz==0)
	{
		printf("通讯录已空\n");
	}
	//1、找到
	char name[NAME_MAX] = { 0 };
	printf("请输入要删除的名字:>");
	scanf("%s", name);
	int pos = FindName(pa, name);
	if (pos == -1)
	{
		printf("要删除的人不存在\n");
		return;
	}
	//2、删除
	int j = 0;
	for (j = pos; j < pa->sz - 1; j++)
	{
		pa->data[j] = pa->data[j + 1];
	}
	pa->sz--;
	printf("删除成功\n");
}

void Printcontact(contact* pa)
{
	assert(pa);
	int i = 0;
	printf("%-10s %-5s %-5s %-12s %-20s\n", "姓名", "年龄", "性别", "电话", "地址");
	for (i = 0; i < pa->sz; i++)
	{
		printf("%-10s %-5d %-5s %-12s %-20s\n", pa->data[i].name,pa->data[i].age,pa->data[i].sex,pa->data[i].tele,pa->data[i].addr);
	}
}

void Searchcontact(const contact* pa)
{
	char name[NAME_MAX] = { 0 };
	printf("请输入要查找的名字:>");
	scanf("%s", name);
	int pos = FindName(pa, name);
	if (pos == -1)
	{
		printf("要查找的人不存在\n");
		return;
	}
	printf("%-10s %-5s %-5s %-12s %-20s\n", "姓名", "年龄", "性别", "电话", "地址");
	printf("%-10s %-5d %-5s %-12s %-20s\n", pa->data[pos].name, pa->data[pos].age, pa->data[pos].sex, pa->data[pos].tele, pa->data[pos].addr);
}
int Cmpname(const void* e1, const void* e2)
{
	return strcmp(((peoinfo*)e1)->name,((peoinfo*)e2)->name);
}
void Sortcontact(contact* pa)
{
	assert(pa);
	qsort(pa->data, pa->sz, sizeof(pa->data[0]), Cmpname);
	printf("排序成功\n");
}

void Modifycontact(contact* pa)
{
	char name[NAME_MAX] = { 0 };
	printf("请输入要修改人的名字:>");
	scanf("%s", name);
	int pos = FindName(pa, name);
	if (pos == -1)
	{
		printf("要修改的人不存在\n");
		return;
	}
	else
	{
		printf("请输入修改后的名字:>");
		scanf("%s", pa->data[pos].name);
		printf("请输入修改后的年龄:>");
		scanf("%d", &(pa->data[pos].age));
		printf("请输入修改后的性别:>");
		scanf("%s", pa->data[pos].sex);
		printf("请输入修改后的电话:>");
		scanf("%s", pa->data[pos].tele);
		printf("请输入修改后的地址:>");
		scanf("%s", pa->data[pos].addr);
		printf("修改成功!!!\n");
	}
	printf("%-10s %-5s %-5s %-12s %-20s\n", "姓名", "年龄", "性别", "电话", "地址");
	printf("%-10s %-5d %-5s %-12s %-20s\n", pa->data[pos].name, pa->data[pos].age, pa->data[pos].sex, pa->data[pos].tele, pa->data[pos].addr);
}

void Destroycontact(contact* pa)
{
	free(pa->data);
	pa->data = NULL;
	pa->capacity = 0;
	pa->sz = 0;
	printf("销毁成功\n");
}

//文件版本
void Savecontact(const contact* pa)
{
	//打开文件
	FILE* pf = fopen("contact.txt", "wb");
	if (pf == NULL)
	{
		perror("Savecontact::fopen");
		return;
	}
	//写文件
	int i = 0;
	for (i = 0; i < pa->sz; i++)
	{
		fwrite(pa->data + i, sizeof(peoinfo), 1, pf);
	}

	//关闭文件
	fclose(pf);
	pf = NULL;
}

test.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("**** 0.退出             ****\n");
	printf("****************************\n");
}

void test()
{
	int input = 0;
	//创建通讯录
	contact con;
	//初始化通讯录
	Initcontact(&con);
	do
	{
		menu();
		printf("请选择功能:>");
		scanf("%d", &input);
		switch (input)
		{
		case ADD:
			Addcontact(&con);
			break;
		case DEL:
			Delcontact(&con);
			break;
		case SEARCH:
			Searchcontact(&con);
			break;
		case MODIFY:
			Modifycontact(&con);
			break;
		case SORT:
			Sortcontact(&con);
			break;
		case PRINT:
			Printcontact(&con);
			break;
		case EXIT:
			Savecontact(&con);
			Destroycontact(&con);
			printf("退出通讯录\n");
			break;
		default:
			printf("选择错误\n");
			break;
		}
	} while (input);
}

int main()
{
	test();
	return 0;
}

你可能感兴趣的:(排序算法,算法)