C语言实现一个简单的通讯录程序

一个合格的通讯录,应该支持增、删、查、改这四个基本操作,同时,我在这个通讯录中也运用了内存的动态管理与文件操作的知识,同时这个通讯录可以支持按照联系人姓名进行排序。

GitHub链接

头文件

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

typedef struct PersonalInfo
{//单个联系人的信息
	char name[1024];
	char sex[20];
	char age[10];
	char phone[1024];
	char address[1024];
}PersonalInfo;

typedef struct AddressBook
{//通讯录
	PersonalInfo* persons;
	int size;//通讯录当前的大小
	int nums;//通讯录的上限
}AddressBook;

AddressBook address_book;

void Init(AddressBook* addr);//初始化
void Relloc_Per(AddressBook* addr);//扩容

int menu();//菜单

void Add_Person_Info(AddressBook* addr);//增加联系人
void Del_Person_Info(AddressBook* addr);//删除联系人
void Find_Person_Info(AddressBook* addr);//查找联系人
void Modify_Person_Info(AddressBook* addr);//修改联系人
void Print_Person_Info(AddressBook* addr);//打印通讯录
void Clear_Person_Info(AddressBook* addr);//清空通讯录

通讯录main函数部分

#include"AddressBook.h"

void Open(AddressBook* addr)//从本地中打开通讯录
{
	FILE* addbook = fopen("C:book.txt", "r");
	if (addbook == NULL)
	{
		perror("文件打开失败!");
		return;
	}
	PersonalInfo buf = { 0 };
	while (fread(&buf, sizeof(PersonalInfo), 1, addbook))
	{
		addr->persons[addr->size] = buf;
		addr->size++;
		if (addr->size >= addr->nums)
		{
			Relloc_Per(addr);
		}
	}
	fclose(addbook);
	return;
}

void Close(AddressBook* addr)//关闭程序时保存通讯录
{
	FILE* addbook = fopen("C:book.txt", "w");
	if (addbook == NULL)
	{
		perror("文件打开失败!");
		return;
	}
	for (int i = 0; i < addr->size; i++)
	{
		fwrite((addr->persons + i), sizeof(PersonalInfo), 1, addbook);
	}
	fclose(addbook);
	return;
}

int main()
{
	Init(&address_book);//初始化通讯录
	Open(&address_book);//打开本地文件
	typedef void(*Func)(AddressBook*);//函数指针
	Func function[] = //函数指针数组
	{
		NULL,//此处为了和menu的返回值匹配,将function[0]的内容写成NULL
		Add_Person_Info,
		Del_Person_Info,
		Find_Person_Info,
		Modify_Person_Info,
		Print_Person_Info,
		Clear_Person_Info
	};
	while (1)
	{
		int choice = menu();
		if (choice == 0)
		{//退出
			Close(&address_book);
			printf("bye!\n\n");
			break;
		}
		if (choice < 0 || choice >= sizeof(function) / sizeof(function[0]))
		{
			printf("输入错误!\n\n");
			continue;
		}
		function[choice](&address_book);//实现具体功能

	}
	return 0;
}

功能函数部分

初始化以及菜单函数

void Init(AddressBook* addr)//初始化通讯录
{
	addr->size = 0;
	addr->nums = 20;
	addr->persons = (PersonalInfo*)malloc((addr->nums) * sizeof(PersonalInfo));
	for (int i = 0; i < addr->nums; i++)
	{
		strcpy(addr->persons[i].name , "");
		strcpy(addr->persons[i].phone , "");
		strcpy(addr->persons[i].address  , "");
		strcpy(addr->persons[i].sex , "");
		strcpy(addr->persons[i].age, "");
	}
}

int menu()//主菜单
{
	printf("============================\n");
	printf("  1.新建联系人\n");
	printf("  2.删除联系人\n");
	printf("  3.查询联系人\n");
	printf("  4.修改联系人\n");
	printf("  5.显示所有联系人\n");
	printf("  6.清空通讯录\n");
	printf("  0.退出\n");
	printf("============================\n\n");

	int ret = 0;
	scanf("%d", &ret);
	return ret;
}

排序以及扩容部分

static void cmp(AddressBook* addr) //排序
{
	int i = 0;
	int j = 0;
	PersonalInfo tmp;
	for (i = 0; i < addr->size - 1; i++)
	{
		for (j = 0; j < addr->size - 1 - i; j++)
		{
			if (strcmp(addr->persons[j].name , addr->persons[j+1].name) > 0)
			{//冒泡排序
				tmp = addr->persons[j];
				addr->persons[j] = addr->persons[j + 1];
				addr->persons[j + 1] = tmp;
			}
		}
	}
}

void Relloc_Per(AddressBook* addr)
{
	addr->nums += 20;
	addr->persons = realloc(addr->persons, (addr->nums) * sizeof(PersonalInfo));
}

增删查改联系人

void Add_Person_Info(AddressBook* addr)//新增联系人
{
	if (addr->size >= addr->nums)
	{
		Relloc_Per(addr);
	}

	PersonalInfo* info = &addr->persons[addr->size];
	printf("新增联系人!\n");

	printf("请输入联系人姓名:");
	scanf("%s", info->name);
	printf("请输入联系人电话:");
	scanf("%s", info->phone);
	printf("请输入联系人性别:");
	scanf("%s", info->sex);
	printf("请输入联系人年龄:");
	scanf("%s", info->age);
	printf("请输入联系人住址:");
	scanf("%s", info->address);

	addr->size++;

	printf("新增联系人成功!\n");

	if (addr->size >= 2)
	{
		cmp(addr);
	}
}

void Del_Person_Info(AddressBook* addr)//删除联系人
{
	if (addr->size <= 0)
	{
		printf("通讯录为空!无法执行删除!\n");
		return;
	}
	printf("删除联系人!\n");
	printf("请输入要删除的联系人序号:");
	int input = 0;
	scanf("%d", &input);
	if (input < 0 || input >= addr->size)
	{
		printf("非法输入!\n");
		return;
	}
	PersonalInfo* last_info = &addr->persons[addr->size - 1];
	PersonalInfo* to_delt = &addr->persons[input];
	*to_delt = *last_info;
	addr->size--;

	printf("联系人成功删除!\n");

	if (addr->size >= 2)
	{
		cmp(addr);
	}
}

void Find_Person_Info(AddressBook* addr)//查找联系人
{
	char find[1024] = { 0 };
	printf("查找联系人!\n");
	printf("请输入想要查找的姓名或联系方式:");
	scanf("%s", &find);
	
	for (int i = 0; i < addr->size; i++)
	{
		PersonalInfo* findinfo = &addr->persons[i];
		if (strcmp(find, findinfo->name) == 0)
		{
			printf("找到了!该联系人编号为:%d\n", i);
			return;
		}
		if (strcmp(find, findinfo->phone) == 0)
		{
			printf("\n找到了!该联系人为:[%d]  姓名:%s   联系方式:%s\n", i,findinfo->name,findinfo->phone);
			return;
		}
	}
	printf("查无此人!\n");

}

void Modify_Person_Info(AddressBook* addr)//修改联系人信息
{
	if (addr->size <= 0)
	{
		printf("通讯录为空!无法执行!\n");
		return;
	}

	int i = 0;
	char name[1024];
	char sex[20];
	char age[10];
	char phone[1024];
	char address[1024];
	printf("修改联系人信息!\n");
	printf("请输入要修改的联系人编号:");
	scanf("%d", &i);
	if (i<0 || i>addr->size)
	{
		printf("输入非法!\n");
		return;
	}
	PersonalInfo* info = &addr->persons[i];

	printf("[%d]  姓名:%s   联系方式:%s \n     性别: %s  年龄: %s\n     住址:%s\n\n", i, info->name, info->phone, info->sex, info->age, info->address);

	printf("请输入要修改的姓名(输入 * 表示不进行修改):");
	scanf("%s", name);
	if (strcmp(name , "*") != 0)
	{
		strcpy(addr->persons[i].name, name);
	}

	printf("请输入要修改的性别(输入 * 表示不进行修改):");
	scanf("%s", sex);
	if (strcmp(sex, "*") != 0)
	{
		strcpy(addr->persons[i].sex, sex);
	}

	printf("请输入要修改的年龄(输入 * 表示不进行修改):");
	scanf("%s", age);
	if (strcmp(age, "*") != 0)
	{
		strcpy(addr->persons[i].age, age);
	}

	printf("请输入要修改的联系方式(输入 * 表示不进行修改):");
	scanf("%s", phone);
	if (strcmp(phone, "*") != 0)
	{
		strcpy(addr->persons[i].phone, phone);
	}

	printf("请输入要修改的地址(输入 * 表示不进行修改):");
	scanf("%s", address);
	if (strcmp(address, "*") != 0)
	{
		strcpy(addr->persons[i].address, address);
	}

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

	if (addr->size >= 2)
	{
		cmp(addr);
	}
}

打印以及清空

void Print_Person_Info(AddressBook* addr)//输出联系人(全部)
{
	printf("显示所有联系人:\n\n");
	for (int i = 0; i < addr->size; i++)
	{
		PersonalInfo* info = &addr->persons[i];
		printf("[%d]  姓名:%s   联系方式:%s \n     性别: %s  年龄: %s\n     住址:%s\n\n", i,info->name ,info->phone,info->sex,info->age,info->address );
	}
	printf("\n到底了...\n");
}

void Clear_Person_Info(AddressBook* addr)//一键清空
{
	char clear[20] = { 0 };
	printf("\n清空通讯录!\n");
	printf("请确认是否清空  (Y/N)\n");
	scanf("%s", clear);

	if (strcmp(clear, "Y") == 0 || strcmp(clear, "y") == 0)
	{
		//addr->size = 0;
		Init(addr);
		printf("成功清空通讯录!\n");
		return;
	}
	else
	{
		printf("放弃清空\n");
	}

}

如此,一个简单的通讯录就可以实现啦。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值