通讯录(C语言文件版本)(超详细过程)-CSDN博客

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6


❇️❇️❇️❇️❇️❇️❇️❇️❇️❇️❇️❇️❇️
❇️❇️❇️❇️ 不同的信念 ❇️❇️❇️❇️
❇️❇️❇️ 决定不同的命运 ❇️❇️❇️
❇️❇️❇️❇️❇️❇️❇️❇️❇️❇️❇️❇️

通讯录

✅具备的功能

ℹ️需要的头文件名

#include<stdio.h>//第一个
#include<string.h>//第二个
#include<stdlib.h>//第三个

第一个头文件名是常规的头文件名如int main主函数和printf函数等都需要只要写C语言都需要此头文件名。

第二个头文件名是在下面执行通讯录文件时需要使用strcmp函数会用到

第三个头文件名也是在下面执行通讯录文件时会用到如qsort函数和free函数会用到

当然这些函数的用途在讲解通讯录的时候会个哦大家介绍。

ℹ️所用到的其它函数和相关结构体

typedef struct Proper//所存储的人的信息
{
	char name[20];//姓名
	int age;//年龄
	char number[20];//电话号码
}Proper;

typedef struct Contact存储人信息的空间
{
	Proper* date;//存储人信息的指针
	int se;//空间里存储联系人信息的数量
	int eff;//空间总的大小
}Contact;

void Inialize(Contact* con)//存储联系人信息的数组初始化
{
	con->date = (Proper*)malloc(3 * sizeof(Proper));
	if (con->date == NULL)
	{
		perror("Inialize");
		return;
	}
	con->se = 0;
	con->eff = 3;
}

void menu()//游戏菜单
{
	printf("*******************************\n");
	printf("***** 1、添加联系人 ***********\n");
	printf("***** 2、删除联系人 ***********\n");
	printf("***** 3、显示联系人 ***********\n");
	printf("***** 4、查找联系人 ***********\n");
	printf("***** 5、修改联系人 ***********\n");
	printf("***** 6、联系人排序 ***********\n");
	printf("***** 7、清空联系人 ***********\n");
	printf("***** 8、退出通讯录 ***********\n");
	printf("*******************************\n");
}
void test()//通讯录函数
{
	int input = 0;
	Contact con;
	Inialize(&con);//通讯录初始化
	do
	{
		menu();//游戏菜单
		printf("请作出选择>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			AddContact(&con);//添加联系人
			break;
		case 2:
			Delete(&con);//删除联系人
			break;
		case 3:
			Display(&con);//显示联系人
			break;
		case 4:
			SeekContact(&con);//查找联系人
			break;
		case 5:
			Modify(&con);//修改联系人
			break;
		case 6:
			SortContact(&con);//联系人排序
			break;
		case 7:
			empty(&con);
			break;
		case 8:
			SaveContact(&con);
			realse(&con);
			printf("退出通讯录\n");
			break;
		default:
			printf("输入有误请重新输入\n");
			break;
		}
		if (input == 8)
			input = 0;
	} while (input);
}
int main()//主函数
{
	test();
	return 0;
}

ℹ️添加联系人

int  Addeff(Contact* con)//检查存储空间是否满的函数
{
	if (con->se == con->eff)//两者相等时会满除了首次进入两个都为0的情况
	{
		Proper* per = (Proper*)realloc(con->date, (con->eff + 2) * sizeof(Proper));
		if (per == NULL)//判断per空间的创建是否成功
		{
			perror("Addeff");
			return 0;
		}
		con->date = per;
		con->eff = con->eff + 2;
		printf("增容成功\n");
	}
	return 1;
}
void AddContact(Contact* con)//添加联系人函数
{
	if (Addeff(con) == 0)//如果Addeff函数如果返回0则表示空间创建失败则不可以添加联系人
	{
		return;
	}

	printf("输入姓名>");
	scanf("%s", con->date[con->se].name);

	printf("输入年龄>");
	scanf("%d", &con->date[con->se].age);//这里会什么会加&地址符呢这是因为输入的是一个数而上面输入不需要加&是因为是数组。数组首元素就是该数组的大小
	
	printf("输入电话号码>");
	
	scanf("%s", con->date[con->se].number);
	
	con->se++;
	printf("添加成功\n");
}

Addeff函数是用来检查我们所用来存储联系人的空间有没有满如果满了就会利用此函数来增加空间。Contact函数就是来添加联系人

ℹ️删除联系人

void Delete(Contact* con)//删除联系人函数
{
	int i = 0;
	char m[20] = { 0 };//创建一个新的数组用来输入你需要查找的联系人的空间
	printf("输入你需要删除联系人的姓名>");
	scanf("%s", m);
	for (i = 0; i < con->se; i++)//在数据里查找你需要删除的联系人的信息
	{
		int j = 0;
		if (strcmp(m, con->date[i].name) == 0)
		{
			for (j = i; j < con->se - 1; j++)//当你找到你所要删除的联系人的消息的时候利用后面的数据把此数据进行覆盖这样就达到删除的功效
			{

				con->date[j] = con->date[j + 1];
			}
			con->se--;//当你删除联系人的时候该联系人后面的数据都往前移了一步这样最后就多了一个空间此时我们就需要删掉这个空间
			printf("删除成功\n");
		}
	}
}

此过程还是很好理解的因为存储联系人的信息是数组所以我们只能利用覆盖来删除。

ℹ️显示联系人

void  Display(Contact* con)//打印通讯录所有联系人信息的函数
{
	int i = 0;
	printf("%-10s  %-10s  %-10s\n", "姓名", "年龄", "电话");
	for (i = 0; i < con->se; i++)
	{
		printf("%-10s  %-10d  %-10s\n", con->date[i].name, con->date[i].age, con->date[i].number);
	}
}

ℹ️查找联系人

void SeekContact(Contact* con)
{
	int i = 0;
	char m[20] = { 0 };//和删除联系人所需创建的变量是同一个意思在这里它就是存储你需要查找的联系人的信息
	printf("输入你要查找的联系人的姓名>");
	scanf("%s", m);
	for (i = 0; i < con->se; i++)//遍历一遍
	{
		if (strcmp(m, con->date[i].name) == 0)//利用了strcmp函数
		{
			printf("找到了姓名:%s, 年龄:%d, 号码:%s\n", con->date[i].name, con->date[i].age, con->date[i].number);
		}
	}
}

strcmp就是用来比较字符串大小的函数它的用法在我以前写的博客中有介绍大家可以去看看字符和字符串的库函数模拟这是一个链接有需要的可以直接点进去看

ℹ️修改联系人

void Modify(Contact* con)//修改联系人信息的函数
{
	char m[20] = { 0 };//这里与上面的用法差不多用来存储你需要查找联系人的信息
	printf("输入你需要修改联系人的姓名>");
	scanf("%s", m);
	int i = 0;
	for (i = 0; i < con->se; i++)//遍历一遍
	{
		if (strcmp(m, con->date[i].name) == 0)//利用了strcmp函数
		{
			printf("重新输入姓名>");
			scanf("%s", con->date[i].name);

			printf("重新输入年龄>");
			scanf("%d", &con->date[i].age);//这里会什么会加&地址符呢这是因为输入的是一个数而上面输入不需要加&是因为是数组。数组首元素就是该数组的大小

			printf("重新输入号码>");
			scanf("%s", con->date[i].number);

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

ℹ️联系人排序

int compare(const void* p1, const void* p2)//比较函数
{
	return strcmp(((Proper*)p1)->name, ((Proper*)p2)->name);
}

void  SortContact(Contact* con)//用来进行联系人排序的函数
{
	qsort(con->date, con->se, sizeof(Proper), compare);//这是一个专门进行排序的函数
	printf("成功排序\n");
}

qsort()函数可以参考相关的博客也可以百度在这里就不做过多解释了抱歉
compare()函数此函数是和qsort函数搭配使用。参考相关资料。抱歉

ℹ️清空联系人

void empty(Contact* con)//清除联系人的函数
{
	con->se = 0;//因为con->se表示的是数组空间类的大小当空间为0的时候这组也就没有数据了
	printf("成功清除\n");
}

ℹ️退出通讯录

当input输入为0的时候程序就退出了

ℹ️通讯录置空

void realse(Contact* con)//通讯录空间置空的函数
{
	free(con->date);//置空函数只要是动态开辟的空间都需要使用该函数进行置空否者就会有内存泄漏的情况
	con->date = NULL;//和free是搭配使用的
	con->se = 0;
	con->eff = 0;
}

关于free函数的用法。大家可以看我以前这篇的博客动态内存管理(c语言)(这是个链接有不清楚的可以点进去观看里面对于懂得太内存有详细的介绍

ℹ️普通的通讯录实现

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct Proper
{
	char name[20];
	int age;
	char number[20];
}Proper;

typedef struct Contact
{
	Proper* date;
	int se;
	int eff;
}Contact;

void menu()
{
	printf("*******************************\n");
	printf("***** 1、添加联系人 ***********\n");
	printf("***** 2、删除联系人 ***********\n");
	printf("***** 3、显示联系人 ***********\n");
	printf("***** 4、查找联系人 ***********\n");
	printf("***** 5、修改联系人 ***********\n");
	printf("***** 6、联系人排序 ***********\n");
	printf("***** 7、清空联系人 ***********\n");
	printf("***** 8、退出通讯录 ***********\n");
	printf("*******************************\n");
}

void Inialize(Contact* con)
{
	con->date = (Proper*)malloc(3 * sizeof(Proper));
	if (con->date == NULL)
	{
		perror("Inialize");
		return;
	}
	con->se = 0;
	con->eff = 3;
}

int  Addeff(Contact* con)
{
	if (con->se == con->eff)
	{
		Proper* per = (Proper*)realloc(con->date, (con->eff + 2) * sizeof(Proper));
		if (per == NULL)
		{
			perror("Addeff");
			return 0;
		}
		con->date = per;
		con->eff = con->eff + 2;
		printf("增容成功\n");
	}
	return 1;
}

void AddContact(Contact* con)
{
	if (Addeff(con) == 0)
	{
		return;
	}

	printf("输入姓名>");
	scanf("%s", con->date[con->se].name);

	printf("输入年龄>");
	scanf("%d", &con->date[con->se].age);

	printf("输入电话号码>");
	scanf("%s", con->date[con->se].number);

	con->se++;

	printf("添加成功\n");

}

void  Display(Contact* con)
{
	int i = 0;
	printf("%-10s  %-10s  %-10s\n", "姓名", "年龄", "电话");
	for (i = 0; i < con->se; i++)
	{
		printf("%-10s  %-10d  %-10s\n", con->date[i].name, con->date[i].age, con->date[i].number);
	}
}

void Delete(Contact* con)
{
	int i = 0;
	char m[20] = { 0 };
	printf("输入你需要删除联系人的姓名>");
	scanf("%s", m);
	for (i = 0; i < con->se; i++)
	{
		int j = 0;
		if (strcmp(m, con->date[i].name) == 0)
		{
			for (j = i; j < con->se - 1; j++)
			{

				con->date[j] = con->date[j + 1];
			}
			con->se--;
			printf("删除成功\n");
		}
	}
}

void SeekContact(Contact* con)
{
	int i = 0;
	char m[20] = { 0 };
	printf("输入你要查找的联系人的姓名>");
	scanf("%s", m);
	for (i = 0; i < con->se; i++)
	{
		if (strcmp(m, con->date[i].name) == 0)
		{
			printf("找到了姓名:%s, 年龄:%d, 号码:%s\n", con->date[i].name, con->date[i].age, con->date[i].number);
		}
	}
}

void Modify(Contact* con)
{
	char m[20] = { 0 };
	printf("输入你需要修改联系人的姓名>");
	scanf("%s", m);
	int i = 0;
	for (i = 0; i < con->se; i++)
	{
		if (strcmp(m, con->date[i].name) == 0)
		{
			printf("重新输入姓名>");
			scanf("%s", con->date[i].name);

			printf("重新输入年龄>");
			scanf("%d", &con->date[i].age);

			printf("重新输入号码>");
			scanf("%s", con->date[i].number);

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

int compare(const void* p1, const void* p2)
{
	return strcmp(((Proper*)p1)->name, ((Proper*)p2)->name);
}

void  SortContact(Contact* con)
{
	qsort(con->date, con->se, sizeof(Proper), compare);
	printf("成功排序\n");
}

void empty(Contact* con)
{
	con->se = 0;
	printf("成功清除\n");
}

void realse(Contact* con)
{
	free(con->date);
	con->date = NULL;
	con->se = 0;
	con->eff = 0;
}

void test()
{
	int input = 0;
	Contact con;
	Inialize(&con);//通讯录初始化
	do
	{
		menu();//游戏菜单
		printf("请作出选择>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			AddContact(&con);//添加联系人
			break;
		case 2:
			Delete(&con);//删除联系人
			break;
		case 3:
			Display(&con);//显示联系人
			break;
		case 4:
			SeekContact(&con);//查找联系人
			break;
		case 5:
			Modify(&con);//修改联系人
			break;
		case 6:
			SortContact(&con);//联系人排序
			break;
		case 7:
			empty(&con);
			break;
		case 8:
			realse(&con);
			printf("退出通讯录\n");
			break;
		default:
			printf("输入有误请重新输入\n");
			break;
		}
		if (input == 8)
			input = 0;
	} while (input);
}

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

上面就是普通的通讯录的实现代码了。有需要的直接复制粘贴就可以了。

✅动态文件操作实现过程

ℹ️联系人信息保存在文件中

void SaveContact(Contact* con)
{
	FILE* fp = fopen("C:\\Users\\杨沛琪\\Desktop\\contact.txt", "wb");//这就是文件的创建
	if (fp == NULL)//这是文件的判断如果创建的文件为空则直接结束该函数不会进行下一步
	{
		perror("fopen");
		return;
	}
	for (int i = 0; i < con->se; i++)
	{
		fwrite(&(con->date[i]), sizeof(Proper), 1, fp);//这是把数组的数据存储到我们刚才创建的文件fp中
	}
	fclose(fp);//文件置空和free用法一样只不过fclose是文件置空使用,free是动态空间使用
	fp = NULL;//和fclose两者是搭配使用的

}

大家如果对于文件方面的操作不太了解的话如FILEfwrite,fread等的用法大家可以观看我的这篇博客文件详细操作过程C语言这是一个链接大家对于文件方面知识的欠缺可以点进去看。

ℹ️从文件中读取联系人的信息

void LoadContact(Contact* con)//读取文件中联系人的信息
{
	FILE* fp = fopen("C:\\Users\\杨沛琪\\Desktop\\contact.txt", "rb");
	if (fp == NULL)
	{
		perror("LoadContact");
		return;
	}
	Proper tem = { 0 };
	while (fread( & tem, sizeof(Proper), 1, fp))//fread()函数是读取文件的函数
	{		
		if (0 == Addeff(con))
			return;
		con->date[con->se] = tem;
		con->se++;
	}
	//为什么要把函数放在while循环中呢这是因为fread的返回值是整数型。它读取一个数据就会返回1读取两个就返回2以此类推当读取的数据为空时就会返回0.
	fclose(fp);//置空函数和free用法一样只不过fclose是文件置空而free是动态空间置空
	fp = NULL;//和fclose搭配使用
}
void Inialize(Contact* con)//存储联系人信息的数组初始化
{
	con->date = (Proper*)malloc(3 * sizeof(Proper));
	if (con->date == NULL)
	{
		perror("Inialize");
		return;
	}
	con->se = 0;
	con->eff = 3;
	LoadContact(con);//和普通的通讯录实现中的初始化仅仅多了这一个函数当我们需要在程序执行前读取文件中所存储的联系人信息只能放在初始化过程中实现。
}

大家如果对于文件方面的操作不太了解的话如FILEfwrite,fread等的用法大家可以观看我的这篇博客文件详细操作过程C语言这是一个链接大家对于文件方面知识的欠缺可以点进去看。

ℹ️通讯录文件形式实现过程

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

typedef struct Proper
{
	char name[20];
	int age;
	char number[20];
}Proper;

typedef struct Contact
{
	Proper* date;
	int se;
	int eff;
}Contact;

void menu()
{
	printf("*******************************\n");
	printf("***** 1、添加联系人 ***********\n");
	printf("***** 2、删除联系人 ***********\n");
	printf("***** 3、显示联系人 ***********\n");
	printf("***** 4、查找联系人 ***********\n");
	printf("***** 5、修改联系人 ***********\n");
	printf("***** 6、联系人排序 ***********\n");
	printf("***** 7、清空联系人 ***********\n");
	printf("***** 8、退出通讯录 ***********\n");
	printf("*******************************\n");
}

int  Addeff(Contact* con);//因为Addeff函数在创建的时候是在下面而在它之前的函数需要调用的时候就会找不到所以就需要提前写一个声明。在C语言中函数执行顺序是从上往下。

void LoadContact(Contact* con)
{
	FILE* fp = fopen("C:\\Users\\杨沛琪\\Desktop\\contact.txt", "rb");
	if (fp == NULL)
	{
		perror("LoadContact");
		return;
	}
	Proper tem = { 0 };
	while (fread( & tem, sizeof(Proper), 1, fp))
	{
		if (0 == Addeff(con))
			return;
		con->date[con->se] = tem;
		con->se++;
	}
	fclose(fp);
	fp = NULL;
}

void Inialize(Contact* con)
{
	con->date = (Proper*)malloc(3 * sizeof(Proper));
	if (con->date == NULL)
	{
		perror("Inialize");
		return;
	}
	con->se = 0;
	con->eff = 3;
	LoadContact(con);
}

int  Addeff(Contact* con)
{
	if (con->se == con->eff)
	{
		Proper* per = (Proper*)realloc(con->date, (con->eff + 2) * sizeof(Proper));
		if (per == NULL)
		{
			perror("Addeff");
			return 0;
		}
		con->date = per;
		con->eff = con->eff + 2;
		printf("增容成功\n");
	}
	return 1;
}

void AddContact(Contact* con)
{
	if (Addeff(con) == 0)
	{
		return;
	}

	printf("输入姓名>");
	scanf("%s", con->date[con->se].name);

	printf("输入年龄>");
	scanf("%d", &con->date[con->se].age);

	printf("输入电话号码>");
	scanf("%s", con->date[con->se].number);

	con->se++;

	printf("添加成功\n");

}

void  Display(Contact* con)
{
	int i = 0;
	printf("%-10s  %-10s  %-10s\n", "姓名", "年龄", "电话");
	for (i = 0; i < con->se; i++)
	{
		printf("%-10s  %-10d  %-10s\n", con->date[i].name, con->date[i].age, con->date[i].number);
	}
}

void Delete(Contact* con)
{
	int i = 0;
	char m[20] = { 0 };
	printf("输入你需要删除联系人的姓名>");
	scanf("%s", m);
	for (i = 0; i < con->se; i++)
	{
		int j = 0;
		if (strcmp(m, con->date[i].name) == 0)
		{
			for (j = i; j < con->se - 1; j++)
			{

				con->date[j] = con->date[j + 1];
			}
			con->se--;
			printf("删除成功\n");
		}
	}
}

void SeekContact(Contact* con)
{
	int i = 0;
	char m[20] = { 0 };
	printf("输入你要查找的联系人的姓名>");
	scanf("%s", m);
	for (i = 0; i < con->se; i++)
	{
		if (strcmp(m, con->date[i].name) == 0)
		{
			printf("找到了姓名:%s, 年龄:%d, 号码:%s\n", con->date[i].name, con->date[i].age, con->date[i].number);
		}
	}
}

void Modify(Contact* con)
{
	char m[20] = { 0 };
	printf("输入你需要修改联系人的姓名>");
	scanf("%s", m);
	int i = 0;
	for (i = 0; i < con->se; i++)
	{
		if (strcmp(m, con->date[i].name) == 0)
		{
			printf("重新输入姓名>");
			scanf("%s", con->date[i].name);

			printf("重新输入年龄>");
			scanf("%d", &con->date[i].age);

			printf("重新输入号码>");
			scanf("%s", con->date[i].number);

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

int compare(const void* p1, const void* p2)
{
	return strcmp(((Proper*)p1)->name, ((Proper*)p2)->name);
}

void  SortContact(Contact* con)
{
	qsort(con->date, con->se, sizeof(Proper), compare);
	printf("成功排序\n");
}

void empty(Contact* con)
{
	con->se = 0;
	printf("成功清除\n");
}

void realse(Contact* con)
{
	free(con->date);
	con->date = NULL;
	con->se = 0;
	con->eff = 0;
}

void SaveContact(Contact* con)
{
	assert(con);
	FILE* fp = fopen("C:\\Users\\杨沛琪\\Desktop\\contact.txt", "wb");
	if (fp == NULL)
	{
		perror("fopen");
		return;
	}
	for (int i = 0; i < con->se; i++)
	{
		fwrite(&(con->date[i]), sizeof(Proper), 1, fp);
	}
	fclose(fp);
	fp = NULL;

}

void test()
{
	int input = 0;
	Contact con;
	Inialize(&con);//通讯录初始化
	do
	{
		menu();//游戏菜单
		printf("请作出选择>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			AddContact(&con);//添加联系人
			break;
		case 2:
			Delete(&con);//删除联系人
			break;
		case 3:
			Display(&con);//显示联系人
			break;
		case 4:
			SeekContact(&con);//查找联系人
			break;
		case 5:
			Modify(&con);//修改联系人
			break;
		case 6:
			SortContact(&con);//联系人排序
			break;
		case 7:
			empty(&con);
			break;
		case 8:
			SaveContact(&con);
			realse(&con);
			printf("退出通讯录\n");
			break;
		default:
			printf("输入有误请重新输入\n");
			break;
		}
		if (input == 8)
			input = 0;
	} while (input);
}

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


✏️✏️✏️✏️✏️✏️✏️✏️✏️✏️✏️✏️✏️
✏️✏️✏️✏️我们一起加油哈✏️✏️
✏️✏️✏️✏️✏️✏️✏️✏️✏️✏️✏️✏️

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6