C语言实现通讯录 提供增删改查等方法(多文件+动态内存+文件存储联系人数据)

	(动态增加内存初始大小为2每次扩容大小为2(修改宏可更改)+文件存储联系人
	数据每次使用时读取文件内容保存在内存中)
	 编译器 vs2013
	通讯录可以用来存储联系人个人的信息,每个人的信息包括:姓 名、性
别、年龄、电话、住址
    提供方法:
		1.添加联系人信息
		2.删除指定联系人信息
		3.查找指定联系人信息
		4.修改指定联系人信息
		5.显示所有联系人信息
		6.清空所有联系人
		7.以名字排序所有联系人

mian.c

#include"test.h"
void menu(){
	printf("╔═══════════════════════════════════════════════════╗\n");
	printf("║═══════════════════  通讯录  ══════════════════════║\n");
	printf("║═══                                             ═══║\n");
	printf("║═══        1.新建联系人      2.删除联系人       ═══║\n");
	printf("║═══        3.查找联系人      4.修改联系人       ═══║\n");
	printf("║═══        5.清空联系人      6.排序联系人       ═══║\n");
	printf("║═══        7.打印联系人      0.退出             ═══║\n");
	printf("║═══                                             ═══║\n");
	printf("╚═══════════════════════════════════════════════════╝\n");
}
int main(){

	int flag = 1;
	int select = 0;
	contact_t *ct=NULL;
	InitContact(&ct);
	while (flag){
		menu();
		int cout = 0;
		printf("请选择:[0-7]#:\n");
		scanf("%d", &select);
		switch (select){
		case 1:
			AddContact(&ct);
			break;
		case 2:
			DelectContact(ct);
			break;
		case 3:
			SearchContact(ct);
			break;
		case 4:
			ModifyContact(ct);
			break;
		case 5:
			ClearContact(ct);
			break;
		case 6:
			SortContact(ct);
			break;
		case 7:
			PrintContact(ct);
			break;
		case 0:
			printf("欢迎下次使用!!!\n");
			SaveContact(ct);
			Sleep(2000);
			flag = 0;
			break;
		default:
			printf("输入有误请重新输入!!!!!\n");
			break;
		}
	}
	system("pause");
	return 0;
}

test.h(头文件)

#ifndef _TEST_H_
#define _TEST_H_
#include<stdio.h>
#include<windows.h>
#include<assert.h>
#pragma warning(disable:4996)
//person内部元素的大小
#define NAME_SIZE 32
#define SEX_SIZE 8
#define TELPHONE_SIZE 16
#define ADDRESS_SIZE 128

#define INIT_NUM 2//通讯录的初始容量
#define INC_NUM 2//扩容大小
//文件信息
#define SAVE_FILE "save.txt"

typedef struct person{
	char name[NAME_SIZE];
	char sex[SEX_SIZE];
	int age;
	char telphone[TELPHONE_SIZE];
	char address[ADDRESS_SIZE];
}person_t;
typedef struct contact{
	int cap;//容量的大小
	int size;//当前存储大小
	person_t contacts[0];//柔性数组
}contact_t;
void AddContact(contact_t **ct);
void InitContact(contact_t **ct);
void SearchContact(contact_t *ct);
void ClearContact(contact_t *ct);
void DelectContact(contact_t *ct);
void ModifyContact(contact_t *ct);
void PrintContact(contact_t *ct);
void SortContact(contact_t *ct);
void SaveContact(contact_t *ct);
#endif

test.c(函数的实现)

#include"test.h"
void InitContact(contact_t **ct)
{
	/*assert(ct);
	*ct = (contact_t *)malloc(sizeof(person_t)*INIT_NUM + sizeof(contact_t));
	if (ct == NULL){
		perror("malloc");
		exit(1);
	}
	memset(*ct, 0, sizeof(person_t)*INIT_NUM + sizeof(contact_t));//对申请的内存进行初始化
	(*ct)->cap = INIT_NUM;*/
	FILE *fp = fopen(SAVE_FILE, "rb");
	if (fp == NULL){
		*ct = (contact_t *)malloc(sizeof(contact_t)+INIT_NUM*sizeof(person_t));
		if (*ct == NULL){
			perror("malloc");
			exit(1);
		}
		(*ct)->size = 0;
		(*ct)->cap = INIT_NUM;
		printf("Using Default Init!\n");
	}
	else{
		contact_t temp;
		fread(&temp, sizeof(contact_t), 1, fp); 
		*ct = (contact_t *)malloc(sizeof(contact_t)+temp.cap * sizeof(person_t));
		if (*ct == NULL){
			perror("malloc");
			exit(2);
		}
		memcpy(*ct, &temp, sizeof(contact_t));
		fread((*ct)->contacts, sizeof(person_t), (*ct)->size, fp);
		printf("Using Sava.txt Init!\n");
		fclose(fp);
	}
}

static int IsFull(contact_t *ct){
	assert(ct);
	return ct->size == ct->cap;
}
static int Inc(contact_t **ct){
	assert(ct);
	contact_t *temp = (contact_t*)realloc(*ct,sizeof(contact_t)+((*ct)->cap + INC_NUM)*sizeof(person_t));
	if (temp == NULL){
		perror("relloc");
		return 0;
	}
	*ct = temp;
	(*ct)->cap += INC_NUM;
	printf("自动扩容成功!!");
	return 1;
}
static IsExist(contact_t *ct, person_t *p){//判断联系人是否存在
	assert(ct);
	assert(p);
	int i = 0;
	for (; i < ct->size; i++){
		if (strcmp(ct->contacts[i].name, p->name)==0){
			return 1;
		}
	}
	return 0;
}
void AddContact(contact_t **ct){//添加联系人
	assert(ct);
	if (!IsFull(*ct) || Inc(ct)){
		person_t p;
		printf("请输入新增联系人的姓名:\n");
		scanf("%s", p.name);
		printf("请输入新增联系人的性别:\n");
		scanf("%s", p.sex);
		printf("请输入新增联系人的年龄:\n");
		scanf("%d", &(p.age));
		printf("请输入新增联系人的电话:\n");
		scanf("%s", p.telphone);
		printf("请输入新增联系人的住址:\n");
		scanf("%s", p.address);
		if (IsExist(*ct, &p)){
			printf("该联系人已经存在!!");
			return;
		}
		else{ 
			memcpy((*ct)->contacts + (*ct)->size, &p, sizeof(p));//拷贝
			(*ct)->size += 1;
		}
	

	}
	else{
		printf("扩容失败!!");
	}
}
static SearchCore(contact_t *ct, char *str){//返回联系人的下标
	int i = 0;
	for (; i < ct->size; i++){
		person_t *p = ct->contacts + i;
		if (strcmp(str, p->name) == 0){
			return i;
		}
	}
	return -1;
}
void SearchContact(contact_t *ct){//查找联系人
	assert(ct);
	printf("请输入你要查找的联系人的姓名:\n");
	char name[NAME_SIZE];
	scanf("%s", name);
	int i = SearchCore(ct, name);
	if (i+1){
			printf("╔═════════════════════════════════════════════════════════════╗\n");
			printf("%3s\t%6s\t%2s%8s%16s%20s\n", "║序号", "姓名", "年龄", "性别", "电话", "地址║");
			printf("%3d\t%6s\t%2d%8s%18s%17s\n",
				i + 1,
				ct->contacts[i].name,
				ct->contacts[i].age,
				ct->contacts[i].sex,
				ct->contacts[i].telphone,
				ct->contacts[i].address);
			printf("╚═════════════════════════════════════════════════════════════╝\n");

	}
	else{
		printf("你要查找的人 %s 不存在!\n", name);
	}
}
void ClearContact(contact_t *ct){
	assert(ct);
	Sleep(2000);
	ct->size = 0;
	printf("通讯录已经清空\n");
}
void DelectContact(contact_t *ct){//删除联系人
	assert(ct);
	char name[NAME_SIZE];
	printf("请输入你要删除的联系人姓名:\n");
	scanf("%s", name);
	int ret = SearchCore(ct, name);
	if (ret){
		ct->contacts[ret] = ct->contacts[(ct->size) - 1];
		(ct->size) -= 1;
	}
	else{
		printf("通讯录中没有联系人%s", name);
	}
}
void ModifyContact(contact_t *ct){//修改联系人
	assert(ct);
	char name[NAME_SIZE];
	printf("请输入你要修改的联系人姓名:\n");
	scanf("%s", name);
	int ret = SearchCore(ct, name);
	if (ret){
		printf("请输入修改后的姓名:\n");
		scanf("%s", ct->contacts[ret].name);
		printf("请输入修改后的年龄:\n");
		scanf("%d", ct->contacts[ret].age);
		printf("请输入修改后的性别:\n");
		scanf("%s", ct->contacts[ret].sex);
		printf("请输入修改后的电话:\n");
		scanf("%s", ct->contacts[ret].telphone);
		printf("请输入修改后的地址:\n");
		scanf("%s", ct->contacts[ret].address);
		printf("原联系人%s修改成功\n", name);
	}
	else{
		printf("通讯录中没有联系人%s", name);
	}
}
static int IsEmpty(contact_t *ct){//判断联系人是否为空
	return (ct->size)==0;
}
void PrintContact(contact_t *ct){//打印联系人
	assert(ct);
		printf("╔═════════════════════════════════════════════════════════════╗\n");
		printf("%3s\t%6s\t%2s%8s%16s%20s\n", "║序号", "姓名", "年龄", "性别", "电话", "地址║");
		for (int i = 0; i < ct->size; i++){
			printf("%3d\t%6s\t%2d%8s%18s%17s\n",
				i + 1,
				ct->contacts[i].name,
				ct->contacts[i].age,
				ct->contacts[i].sex,
				ct->contacts[i].telphone,
				ct->contacts[i].address);
		}
		printf("╚═════════════════════════════════════════════════════════════╝\n");
}
static int Compare(const void *p1, const void *p2){//使用qsort时提供的回调函数
	assert(p1);
	assert(p2);
	person_t *_p1 = (person_t*)p1;
	person_t *_p2 = (person_t*)p2;
	return strcmp(_p1->name, _p2->name);
}
void SortContact(contact_t *ct){
	assert(ct);
	if (!IsEmpty(ct)){
		qsort(ct->contacts, ct->size, sizeof(person_t), Compare);
	}
}
void SaveContact(contact_t *ct){//退出时将数据保存到文件中
	assert(ct);
	FILE *fp = fopen(SAVE_FILE, "wb");
	if (fp == NULL){
		perror("svae error!\n");
		return;
	}
	fwrite(ct, sizeof(contact_t), 1, fp);
	fwrite(ct->contacts, sizeof(person_t), ct->size, fp);
}

运行界面:
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值