通讯录文件版本

目录

前言

构造框架 

 功能实现

Init

Exit

SaveContact 

Destory 

add 

Delete 

 Search

Modify

Sort_byname 

Print 

完整代码

contact.h

contact.c 

test.c 


前言

通讯录用来存储联系人信息:名字,性别,年龄,电话,地址。

基本功能:1.添加联系人信息 2.删除联系人信息 3.查找联系人 4.修改联系人信息

5.打印信息 6.按照名字对联系人进行排序。

构造框架 

首先创建菜单,再建立框架,将菜单和功能联系起来。

void menu()
{
	printf("**************************************\n");
	printf("********1.ADD          2.Delete*******\n");
	printf("********3.Search       4.Modify*******\n");
	printf("********5.Print        6.Sort*********\n");
	printf("********        0.exit        ********\n");
	printf("**************************************\n");
}
void test()
{
	contact c1;
	Init(&c1);
	int input = 0;
	do
	{
		menu();
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			Add(&c1);
			break;
		case 2:
			Delete(&c1);
			break;
		case 3:
			Search(&c1);
			break;
		case 4:
			Modify(&c1);
			break;
		case 5:
			Print(&c1);
			break;
		case 6:
			Sort_byname(&c1);
			break;
		case 0:
			SaveContact(&c1);//保留数据
			Destory(&c1);
			break;
		default:
			printf("输入非法,请重新输入\n");
			break;
		}
	} while (input);
}

接下来构造结构体。 

typedef struct Private //联系人信息
{
	char name[20];//名字
	char sex[5];//性别
	int age;//年龄
	char phone[15];//电话
	char address[20];//地址
}Private;

typedef struct contact//通讯录
{
	Private* data;
	int size;//已存联系人个数
	int capacity;//容量
}contact;

 功能实现

Init

初始化过程要把文件中的信息读取到通讯录。在读取过程中,若空间已满则要开辟新的空间。

总结初始化分为两步:检查空间和加载信息

检查空间 

void check(contact* c1)//检查是否满
{
	assert(c1);
	if (c1->size == c1->capacity)
	{
		Private* tmp = (Private*)realloc(c1->data, sizeof(Private)*(c1->capacity + 2));
		if (tmp == NULL)
		{
			printf("扩容失败\n");
			return;
		}
		c1->data = tmp;
		c1->capacity += 2;
		printf("增容成功\n");
	}
}

加载信息 

void LoadContact(contact* c1)//加载信息到通讯录
{
	assert(c1);
	//打开文件
	FILE* pf = fopen("contact.txt", "rb");//以二进制读方式打开
	if (pf == NULL)
	{
		perror("open:");//打印错误信息
		return;
	}
	//读入数据
	while (fread(c1->data + (c1->size), sizeof(Private), 1, pf))
	{
		c1->size++;
		check(c1);//检查元素是否溢出
	}
	//关闭文件
	fclose(pf);
	pf = NULL;
	
}

合并

void Init(contact* c1) //初始化
{
	assert(c1);
	c1->size = 0;
	c1->capacity = 4;
	Private* tmp = (Private*)malloc(sizeof(Private) * c1->capacity);
	if (tmp == NULL)
	{
		printf("初始化失败");
		return;
	}
	c1->data = tmp;
	memset(c1->data, 0, sizeof(c1->data));
	LoadContact(c1);//把文件信息加载到通讯录
}

Exit

退出通讯录时,要将通讯录中的信息存到文件中,并销毁通讯录。

分装成 SaveContactDestory两个函数实现。

SaveContact 

void SaveContact(contact* c1)
{
	FILE* pf = fopen("contact.txt", "wb");//以二进制写形式保留数据
	if (pf == NULL)
	{
		perror("OPEN:");
		return;
	}
	//写入文件
	for (int i = 0; i < c1->size; i++)
	{
		fwrite(c1->data + i, sizeof(Private), 1, pf);
	}
	//关闭文件
	fclose(pf);
	pf = NULL;
}

Destory 

void Destory(contact* c1) 
{
	assert(c1);
	
	free(c1->data);
	c1->data = NULL;
	c1->capacity = c1->size = 0;
	printf("销毁成功");
}

add 

每次添加信息也要判断空间是否满。

void Add(contact* c1)
{
	assert(c1);
	check(c1);//检查通讯录是否满
	printf("请输入添加人的姓名->");
	scanf("%s", c1->data[c1->size].name);
	printf("请输入添加人的性别->");
	scanf("%s", c1->data[c1->size].sex);
	printf("请输入添加人的年龄->");
	scanf("%d", &c1->data[c1->size].age);
	printf("请输入添加人的电话->");
	scanf("%s", c1->data[c1->size].phone);
	printf("请输入添加人的地址:->");
	scanf("%s", c1->data[c1->size].address);
	printf("添加成功\n");
	c1->size++;
}

Delete 

要删除一个联系人的信息,首先要检查这个联系人是否存在。所以这里要再实现一个按名查找功能。

int find_name(contact* c1,char *s)//找到联系人的位置
{
	assert(c1);
	for (int i = 0; i < c1->size; i++)
	{
		if (strcmp(s, c1->data[i].name) == 0)
		{
			return i;
		}
	}
	return -1;
}
void Delete(contact* c1)
{
	assert(c1);
	if (c1->size == 0)
	{
		printf("通讯录已空,无法删除\n");
		return;
	}
	char a[20] = { 0 };
	printf("请输入要删除人的名字->");
	scanf("%s", a);
	int pos = find_name(c1,a);
	if (pos == -1)
	{
		printf("没有该联系人,无法删除\n");
		return;
	}
	else
	{
		for (int i = pos; i < c1->size-1; i++)
		{
			c1->data[i] = c1->data[i + 1];
		}
	}
	printf("删除成功\n");
	c1 ->size--;
}

 Search

查找功能也要使用fine_name函数判断联系人是否存在。

void Search(contact* c1)
{
	assert(c1);
	char a[20] = { 0 };
	printf("请输入要查找的人名字->");
	scanf("%s", a);
	int pos = find_name(c1, a);
	if (pos == -1)
	{
		printf("无该联系人\n");
		return;
	}
	else
	{
		printf("%-20s %-5s %-5s %-15s %-30s\n", "姓名", "性别", "年龄", "电话", "地址");
		printf("%-20s %-5s %-5d %-15s %-30s\n ", c1->data[pos].name,c1->data[pos].sex,c1->data[pos].age,c1->data[pos].phone,c1->data[pos].address);
	}	
}

Modify

修改联系人信息。

void Modify(contact* c1)
{
	assert(c1);
	char a[20] = { 0 };
	printf("请输入要修改的人名字:");
	scanf("%s", a);
	int pos = find_name(c1, a);
	if (pos == -1)
	{
		printf("无该联系人,无法修改\n");
		return;
	}
	else
	{
		printf("请输入新姓名:");
		scanf("%s", c1->data[pos].name);
		printf("请输入新性别:");
		scanf("%s", c1->data[pos].sex);
		printf("请输入新年龄:");
		scanf("%d", &c1->data[pos].age);
		printf("请输入新电话:");
		scanf("%s", c1->data[pos].phone);
		printf("请输入新地址:");
		scanf("%s", c1->data[pos].address);
		printf("修改成功\n");
	}
}

Sort_byname 

这里按名排序功能,采用冒泡排序方式实现。

void Sort_byname(contact* c1)
{
	assert(c1);
	for (int i = 0; i < c1->size-1; i++)//冒泡排序
	{
		for (int j = 1; j <= c1->size - 1 - i; j++)
		{
			if (strcmp(c1->data[j - 1].name, c1->data[j].name)>0)
			{
				Private tmp = c1->data[j-1];
				c1->data[j - 1] = c1->data[j];
				c1->data[j] = tmp;

			}
		}
	}
	printf("排序成功\n");

}

Print 

将通讯录中所有联系人信息打印出来。

void Print(contact* c1)
{
	assert(c1);
	if (c1->size == 0)//先判断通讯录是否为空
	{
		printf("通讯录已空,无法打印\n");
		return;
	}
	printf("%-30s %-5s %-5s %-15s %-30s\n", "姓名","性别","年龄","电话","地址");
	for (int i = 0; i < c1->size; i++)
	{
		printf("%-30s %-5s %-5d %-15s %-30s\n", c1->data[i].name,c1->data[i].sex,c1->data[i].age,c1->data[i].phone,c1->data[i].address);
	}
}

以上就是通讯录的实现过程了。 

完整代码

contact.h

#include<assert.h>
#include<string.h>
#define _CRT_SECURE_NO_WARNINGS 1
typedef struct Private//个人信息
{
	char name[20];//名字
	char sex[5];//性别
	int age;//年龄
	char phone[15];//电话
	char address[20];//地址
}Private;

typedef struct contact//通讯录
{
	Private* data;
	int size;//个数
	int capacity;//容量
}contact;
int find_name(contact* c1, char* s);
void check(contact* c1);
void Init(contact* c1);
void Destory(contact* c1);
void Add(contact* c1);
void Delete(contact* c1);
void Search(contact* c1);
void Modify(contact* c1);
void Print(contact* c1);
void Sort_byname(contact* c1);
void SaveContact(contact* c1);

contact.c 

#include"contact.h"

void LoadContact(contact* c1)
{
	assert(c1);
	//打开文件
	FILE* pf = fopen("contact.txt", "rb");//以二进制读方式打开
	if (pf == NULL)
	{
		perror("open:");//打印错误信息
		return;
	}
	//读入数据
	while (fread(c1->data + (c1->size), sizeof(Private), 1, pf))
	{
		c1->size++;
		check(c1);//检查元素是否溢出
	}
	//关闭文件
	fclose(pf);
	pf = NULL;
	
}
void Init(contact* c1) //初始化
{
	assert(c1);
	c1->size = 0;
	c1->capacity = 4;
	Private* tmp = (Private*)malloc(sizeof(Private) * c1->capacity);
	if (tmp == NULL)
	{
		printf("初始化失败");
		return;
	}
	c1->data = tmp;
	memset(c1->data, 0, sizeof(c1->data));
	LoadContact(c1);//把文件信息加载到通讯录
}
void Destory(contact* c1) 
{
	assert(c1);
	
	free(c1->data);
	c1->data = NULL;
	c1->capacity = c1->size = 0;
	printf("销毁成功");
}
void check(contact* c1)//检查是否满
{
	assert(c1);
	if (c1->size == c1->capacity)
	{
		Private* tmp = (Private*)realloc(c1->data, sizeof(Private)*(c1->capacity + 2));
		if (tmp == NULL)
		{
			printf("扩容失败\n");
			return;
		}
		c1->data = tmp;
		c1->capacity += 2;
		printf("增容成功\n");
	}
}
void Add(contact* c1)
{
	assert(c1);
	check(c1);//检查通讯录是否满
	printf("请输入添加人的姓名->");
	scanf("%s", c1->data[c1->size].name);
	printf("请输入添加人的性别->");
	scanf("%s", c1->data[c1->size].sex);
	printf("请输入添加人的年龄->");
	scanf("%d", &c1->data[c1->size].age);
	printf("请输入添加人的电话->");
	scanf("%s", c1->data[c1->size].phone);
	printf("请输入添加人的地址:->");
	scanf("%s", c1->data[c1->size].address);
	printf("添加成功\n");
	c1->size++;
}
void Print(contact* c1)
{
	assert(c1);
	if (c1->size == 0)
	{
		printf("通讯录已空,无法打印\n");
		return;
	}
	printf("%-30s %-5s %-5s %-15s %-30s\n", "姓名","性别","年龄","电话","地址");
	for (int i = 0; i < c1->size; i++)
	{
		printf("%-30s %-5s %-5d %-15s %-30s\n", c1->data[i].name,c1->data[i].sex,c1->data[i].age,c1->data[i].phone,c1->data[i].address);
	}
}
int find_name(contact* c1,char *s)//找到联系人的位置
{
	assert(c1);
	for (int i = 0; i < c1->size; i++)
	{
		if (strcmp(s, c1->data[i].name) == 0)
		{
			return i;
		}
	}
	return -1;
}
void Delete(contact* c1)
{
	assert(c1);
	if (c1->size == 0)
	{
		printf("通讯录已空,无法删除\n");
		return;
	}
	char a[20] = { 0 };
	printf("请输入要删除人的名字->");
	scanf("%s", a);
	int pos = find_name(c1,a);
	if (pos == -1)
	{
		printf("没有该联系人,无法删除\n");
		return;
	}
	else
	{
		for (int i = pos; i < c1->size-1; i++)
		{
			c1->data[i] = c1->data[i + 1];
		}
	}
	printf("删除成功\n");
	c1 ->size--;
}
void Search(contact* c1)
{
	assert(c1);
	char a[20] = { 0 };
	printf("请输入要查找的人名字->");
	scanf("%s", a);
	int pos = find_name(c1, a);
	if (pos == -1)
	{
		printf("无该联系人\n");
		return;
	}
	else
	{
		printf("%-20s %-5s %-5s %-15s %-30s\n", "姓名", "性别", "年龄", "电话", "地址");
		printf("%-20s %-5s %-5d %-15s %-30s\n ", c1->data[pos].name,c1->data[pos].sex,c1->data[pos].age,c1->data[pos].phone,c1->data[pos].address);
	}	
}

void Modify(contact* c1)
{
	assert(c1);
	char a[20] = { 0 };
	printf("请输入要修改的人名字:");
	scanf("%s", a);
	int pos = find_name(c1, a);
	if (pos == -1)
	{
		printf("无该联系人,无法修改\n");
		return;
	}
	else
	{
		printf("请输入新姓名:");
		scanf("%s", c1->data[pos].name);
		printf("请输入新性别:");
		scanf("%s", c1->data[pos].sex);
		printf("请输入新年龄:");
		scanf("%d", &c1->data[pos].age);
		printf("请输入新电话:");
		scanf("%s", c1->data[pos].phone);
		printf("请输入新地址:");
		scanf("%s", c1->data[pos].address);
		printf("修改成功\n");
	}
}
void Sort_byname(contact* c1)
{
	assert(c1);
	for (int i = 0; i < c1->size-1; i++)
	{
		for (int j = 1; j <= c1->size - 1 - i; j++)
		{
			if (strcmp(c1->data[j - 1].name, c1->data[j].name)>0)
			{
				Private tmp = c1->data[j-1];
				c1->data[j - 1] = c1->data[j];
				c1->data[j] = tmp;

			}
		}
	}
	printf("排序成功\n");

}
void SaveContact(contact* c1)
{
	FILE* pf = fopen("contact.txt", "wb");//以二进制写形式保留数据
	if (pf == NULL)
	{
		perror("OPEN:");
		return;
	}
	//写入文件
	for (int i = 0; i < c1->size; i++)
	{
		fwrite(c1->data + i, sizeof(Private), 1, pf);
	}
	//关闭文件
	fclose(pf);
	pf = NULL;
}

test.c 

#include"contact.h"
void menu()
{
	printf("**************************************\n");
	printf("********1.ADD          2.Delete*******\n");
	printf("********3.Search       4.Modify*******\n");
	printf("********5.Print        6.Sort*********\n");
	printf("********        0.exit        ********\n");
	printf("**************************************\n");
}
void test()
{
	contact c1;
	Init(&c1);
	int input = 0;
	do
	{
		menu();
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			Add(&c1);
			break;
		case 2:
			Delete(&c1);
			break;
		case 3:
			Search(&c1);
			break;
		case 4:
			Modify(&c1);
			break;
		case 5:
			Print(&c1);
			break;
		case 6:
			Sort_byname(&c1);
			break;
		case 0:
			SaveContact(&c1);//保留数据
			Destory(&c1);
			break;
		default:
			printf("输入非法,请重新输入\n");
			break;
		}
	} while (input);
}
int main()
{
	test();
	return 0;
}

 希望对你有所帮助。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

嚞譶

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

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

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

打赏作者

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

抵扣说明:

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

余额充值