动态内存、文件操作的练习——通讯录改进

这是一个使用C语言编写的简单通讯录管理系统,包括添加、删除、查找、修改和显示联系人信息的功能。程序通过文件存储数据,并进行了内存管理以适应数据增删。此外,还实现了按姓名排序的操作。

对该代码的改进

contact.h

#pragma warning(disable:6031)

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

#define DEFAULT_SIZE 3

enum
{
	MAX_NAME = 20,
	MAX_SEX = 5,
	MAX_TELE = 13,
	MAX_ADDRESS = 100
};

enum
{
	Exit,
	Add,
	Delete,
	Search,
	Modify,
	Show,
};

struct People
{
	char name[MAX_NAME];
	char sex[MAX_SEX];
	int age;
	char tele[MAX_TELE];
	char address[MAX_ADDRESS];
};

struct Contact
{
	struct People* information;
	int capacity;//记录通讯录当前容量
	int size;//记录通讯录中联系人个数
};

//初始化通讯录
void InitContact(struct Contact* con);
//打印联系人信息
void ShowContact(const struct Contact* con);
//添加联系人信息
void AddContact(struct Contact* con);
//删除联系人信息
void DeleteContact(struct Contact* con);
//更改联系人信息
void ModifyContact(struct Contact* con);
//查找联系人信息
void SearchContact(const struct Contact* con);
//保存联系人信息
void SaveContact(const struct Contact* con);

text.c

#define _CRT_SECURE_NO_WARNINGS

#include"contact.h"

void Menu()
{
	printf("1.Add   \t2.Delete\n");
	printf("3.Search\t4.Modify\n");
	printf("5.Show  \t0.Exit\n");
	printf("---------------------------\n");
}

int main()
{
	//创建通讯录
	struct Contact con;//con包含联系人信息和size和capacity
	//初始化通讯录
	InitContact(&con);
	int input = 0;
	do
	{
		Menu();
		scanf("%d", &input);
		system("cls");
		switch (input)
		{
		case Add:
			AddContact(&con);
			break;
		case Delete:
			DeleteContact(&con);
			break;
		case Search:
			SearchContact(&con);
			break;
		case Modify:
			ModifyContact(&con);
			break;
		case Show:
			ShowContact(&con);
			break;
		case Exit:
			SaveContact(&con);
			printf("保存成功,退出\n");
			break;
		default:
			printf("输入错误\n");
		}
	} while (input);
	return 0;
}

contact.c

#define _CRT_SECURE_NO_WARNINGS

#include"contact.h"

static void CheckCapacity(struct Contact* con);

void SaveContact(const struct Contact* con)
{
	FILE* pfwrite = fopen("../contact.data", "wb");
	if (pfwrite == NULL)
	{
		printf("SaveContact:%s\n", strerror(errno));
		return;
	}
	
	for (int i = 0; i < con->size; i++)
	{
		fwrite(&(con->information[i]), sizeof(struct People), 1, pfwrite);
	}

	fclose(pfwrite);
	pfwrite = NULL;

}

static void LoadContact(struct Contact* con)
{
	struct People temp = { 0 };
	FILE* pfread = fopen("../contact.data", "rb");
	if (pfread == NULL)
	{
		printf("LoadContact:%s\n", strerror(errno));
		return;
	}

	while (fread(&temp, sizeof(struct People), 1, pfread))
	{
		CheckCapacity(con);
		con->information[con->size] = temp;
		con->size++;
	}

	fclose(pfread);
	pfread = NULL;
	system("cls");
}

static void CheckCapacity(struct Contact* con)
{
	if (con->size == con->capacity)
	{
		struct People* ptr = (struct People*)realloc(con->information, (con->capacity + 2) * sizeof(struct People));
		if (ptr == NULL)
		{
			printf("CheckCapacity:%s\n", strerror(errno));
			return;
		}
		con->information = ptr;
		printf("增容成功\n");
	}
}

static void SortContact(struct Contact* con)
{
	int i = 0, j = 0;
	for (i = 0; i < con->size - 1; i++)
	{
		struct People temp = con->information[i];
		for (j = i + 1; j < con->size; j++)
		{
			if (strcmp(con->information[i].name, con->information[j].name) > 0)
			{
				con->information[i] = con->information[j];
				con->information[j] = temp;
			}
		}
	}
}

static int FindByName(const struct Contact* con, char* name)
{
	for (int i = 0; i < con->size; i++)
	{
		if (strcmp(con->information[i].name, name) == 0)
			return i;
	}
	return -1;
}

void InitContact(struct Contact* con)
{
	con->information = (struct People*)malloc(DEFAULT_SIZE * sizeof(struct People));
	if (con->information == NULL)
	{
		printf("InitContact:%s\n", strerror(errno));
		return;
	}
	con->capacity = DEFAULT_SIZE;
	con->size = 0;
	LoadContact(con);
}

void ShowContact(const struct Contact* con)
{
	if (con->size == 0)
		printf("通讯录为空\n");
	else
	{
		//设置标头
		printf("%-10s\t%-3s\t%-3s\t%-15s\t%-20s\n", "姓名","性别","年龄","电话","住址");
		for (int i = 0; i < con->size; i++)
		{
			printf("%-10s\t%-3s\t%-3d\t%-15s\t%-20s\n",
				con->information[i].name,
				con->information[i].sex,
				con->information[i].age,
				con->information[i].tele,
				con->information[i].address);
		}
	}
}

void AddContact(struct Contact* con)
{
	CheckCapacity(con);

	printf("请输入要添加联系人的名字:");
	scanf("%s", &con->information[con->size].name);
	printf("请输入要添加联系人的性别:");
	scanf("%s", &con->information[con->size].sex);
	printf("请输入要添加联系人的年龄:");
	scanf("%d", &con->information[con->size].age);
	printf("请输入要添加联系人的电话:");
	scanf("%s", &con->information[con->size].tele);
	printf("请输入要添加联系人的地址:");
	scanf("%s", &con->information[con->size].address);

	con->size++;

	SortContact(con);
	printf("添加成功\n");
}

void DeleteContact(struct Contact* con)
{
	int pos = 0;
	char name[MAX_NAME] = { 0 };
	printf("请输入要删除的联系人的姓名:");
	scanf("%s", &name);

	pos = FindByName(con,name);

	if (pos == -1)
		printf("该联系人不存在\n");
	else
	{
		for (int i = pos; i < con->size; i++)
		{
			con->information[i] = con->information[i + 1];
		}
		con->size--;
		printf("删除成功\n");
	}
}

void ModifyContact(struct Contact* con)
{
	int pos = 0;
	char name[MAX_NAME] = { 0 };
	printf("请输入要更改的联系人的姓名:");
	scanf("%s", &name);

	pos = FindByName(con, name);

	printf("请输入新的联系人的名字:");
	scanf("%s", &con->information[pos].name);
	printf("请输入新的联系人的性别:");
	scanf("%s", &con->information[pos].sex);
	printf("请输入新的联系人的年龄:");
	scanf("%d", &con->information[pos].age);
	printf("请输入新的联系人的电话:");
	scanf("%s", &con->information[pos].tele);
	printf("请输入新的联系人的地址:");
	scanf("%s", &con->information[pos].address);

	SortContact(con);
	printf("更改成功\n");
}

void SearchContact(const struct Contact* con)
{
	char name[MAX_NAME] = { 0 };
	int pos = 0;
	printf("请输入要查找的联系人的姓名:");
	scanf("%s", &name);

	pos = FindByName(con, name);

	if (pos == -1)
		printf("该联系人不存在\n");
	else
	{
		printf("%-10s\t%-3s\t%-3s\t%-15s\t%-20s\n", "姓名", "性别", "年龄", "电话", "住址");
		printf("%-10s\t%-3s\t%-3d\t%-15s\t%-20s\n",
			con->information[pos].name,
			con->information[pos].sex,
			con->information[pos].age,
			con->information[pos].tele,
			con->information[pos].address);
	}
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值