c语言实现通讯录管理系统(附源码和详细注解)

今天学完了c语言,这是我编写的通讯录管理系统,亲测有效,没有问题:

基本功能有:

1、添加联系人

2、查找一个联系人

3、修改联系人

4、删除一个联系人

5、展示所有联系人

6、清空所有联系人

7、以名字排序所有联系人

此外,此程序还支持动态扩容和文件操作(保存和读取功能),注意文件位置,得先创建。这里还有一点需要注意,我在对文件操作的时候直接复制了它的路径,结果程序报错,后来把‘\’改成了‘/’就可以了。

#define  _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<windows.h>
#include<math.h>
//描述了一个联系人
typedef struct Linkman {
	char name[1024];
	char gender[1024];
	char age[1024];
	char number[1024];
	char address[1024];
}Linkman;

//描述了一个通讯录,里面包含了多个联系人,size是当前联系人数
typedef struct AddressList {
	//把这个数组改成指针,通过malloc来动态分配内存
	Linkman* persons;
	//表示当前这个指针指向的数组的最大容量
	int capacity;
	int size;
}AddressList;

//创建一个全局变量
AddressList addressList;

//保存内容到文件(存档)
void save(AddressList* list) {
	FILE* fp = fopen("E:/address_list.txt", "w");
	//查看是否打开成功
	if (fp == NULL) {
		printf("打开存档文件失败\n");
		return;
	}
	//使用fwrite来写
	fwrite(list->persons, sizeof(Linkman), list->size, fp);
	fclose(fp);
	printf("存档成功\n");
}

//函数声明
//extern void save(AddressList* list);

//把文件中数据加载到内存中(读档)
void load(AddressList* list) {
	FILE* fp = fopen("E:/address_list.txt", "r");
	if (fp == NULL) {
		printf("打开存档文件失败\n");
		return;
	}
	//写文件中,一共要读多少个元素,直接通过size就知道了
	//读文件中,一共要读多少元素就不好确定,只能一个一个读,直到读到文件末尾 
	while (1) {
		if (list->size > list->capacity) {
			list->capacity += 100;
			list->persons = realloc(list->persons, sizeof(Linkman) * list->capacity);
		}
		size_t n = fread(&list->persons[list->size], sizeof(Linkman), 1, fp);
		if (n == 0) {
			//读到文件末尾了
			break;
		}
		list->size++;
	}
	fclose(fp);
	printf("读档成功!\n");
}

//初始化
void init(AddressList* list) {
	list->size = 0;
	list->capacity = 100;
	list->persons = (Linkman*)malloc(sizeof(Linkman) * list->capacity);
	//(list->num).name = { 0 };
}

int menu() {
	printf("+----------------------------+\n");
	printf("|      通讯录管理系统        |\n");
	printf("+----------------------------+\n");
	printf("|    1、添加联系人           |\n");
	printf("|    2、查找一个联系人       |\n");
	printf("|    3、修改联系人           |\n");
	printf("|    4、删除联系人           |\n");
	printf("|    5、展示所有联系人       |\n");
	printf("|    6、清空所有联系人       |\n");
	printf("|    7、以名字排序所有联系人 |\n");
	printf("|    0、退出                 |\n");
	printf("+----------------------------+\n");
	printf("请输入你的选择:");
	int choice = 0;
	scanf("%d", &choice);
	return choice;
}

//添加联系人
void insert(AddressList* list) {
	assert(list != NULL);
	//通讯录满了的话就返回
	/*if (list->size >= 1000) {
		printf("通讯录已满\n");
		return;
	}*/
	//进行扩容
	if (list->size > list->capacity) {
		list->capacity += 100;
		list->persons = (Linkman*)realloc(list->persons, sizeof(Linkman) * list->capacity);
	}
	Linkman person = { 0 };
	printf("请输入联系人姓名:");
	scanf("%s", person.name);
	printf("请输入联系人性别:");
	scanf("%s", person.gender);
	printf("请输入联系人年龄:");
	scanf("%s", person.age);
	printf("请输入联系人电话:");
	scanf("%s", person.number);
	printf("请输入联系人住址:");
	scanf("%s", person.address);
	//把联系人放在通讯录中
	list->persons[list->size] = person;
	list->size++;
	printf("新增联系人成功\n");
	//Sleep(2000); //显示两秒
	//system("cls");
	save(list);
}
//修改联系人
void change(AddressList* list) {
	int id = 0;
	printf("请输入你要修改的联系人的序号:");
	scanf("%d", &id);
	if (id < 0 || id > list->size - 1) {
		printf("你的输入有误");
		return;
	}
	Linkman* p = &list->persons[id];
	printf("请输入修改后的联系人的姓名:");
	scanf("%s", p->name);
	printf("请输入修改后的联系人的性别:");
	scanf("%s", p->gender);
	printf("请输入修改后的联系人的年龄:");
	scanf("%s", p->age);
	printf("请输入修改后的联系人的电话:");
	scanf("%s", p->number);
	printf("请输入修改后的联系人的住址:");
	scanf("%s", p->address);
	printf("修改联系人成功!\n");
	save(list);
}

//查找联系人
void find(AddressList* list) {
	int id = 0;
	printf("请输入要查看联系人的序号:");
	scanf("%d", &id);
	if (id < 0 || id > list->size - 1) {
		printf("你的输入有误");
		return;
	}
	for (int i = 0; i < list->size; i++) {
		if (id == i) {
			Linkman* p = &list->persons[i];
			printf("姓名:%s\t性别:%s\t年龄:%s\t电话:%s\t住址:%s\n", p->name, p->gender, p->age, p->number, p->address);
			printf("%s", list->persons[i].name);
		}
	}
}
//查看所有联系人
void show(AddressList* list) {
	//printf("查看所有联系人\n");
	for (int i = 0; i < list->size; i++) {
		Linkman* p = &list->persons[i];
		printf("[%d]\t%s\t%s\n", i, p->name, p->number);
	}
	printf("一共有%d个联系人\n", list->size);
}
//清空所有联系人
void empty(AddressList* list) {
	int i = 0;
	printf("确定要清空所有联系人吗,确定请按1,按其余键返回\n");
	scanf("%d", &i);
	if (i == 1) {
		list->size = 0;
		printf("删除成功!\n");
	}
	return;
	save(list);
}
//按照姓名排序
void sort(AddressList* list) {
	for (int i = 0; i < list->size - 1; i++) {
		for (int j = 0; j < list->size - 1 - i; j++) {
			Linkman* p1 = &list->persons[j];
			Linkman* p2 = &list->persons[j + 1];
			if (memcmp(p1->name, p2->name, sizeof(p1->name)) > 0) {
				Linkman tmp = list->persons[j];
				list->persons[j] = list->persons[j + 1];
				list->persons[j + 1] = tmp;
			}
		}
	}
	printf("排序成功!\n");
	save(list);
}

//删除一个联系人(逻辑删除)
void update(AddressList* list) {
	int id = 0;
	printf("请输入要删除的联系人的序号:\n");
	scanf("%d", &id);
	if (id < 0 || id > list->size) {
		printf("你的输入有误\n");
		return;
	}
	else if (id == list->size - 1) {//要删除的是最后一个联系人
		list->size--;
		printf("删除成功!\n");
	}
	//取出最后一个联系人的地址
	Linkman* p = &list->persons[list->size - 1];
	list->persons[id] = *p;
	list->size--;
	printf("删除成功!\n");
	save(list);
}


//定义一个函数指针
typedef void(*Func)(AddressList*);

int main() {
	init(&addressList);
	//定义一个函数指针数组
	load(&addressList);//程序启动前进行一次读档即可
	//为了降低圈复杂度,采用转移表的方式
	Func func[] = { NULL,insert,find,change,update,show,empty,sort };//NULL纯粹为了占位
	while (1) {
		int choice = menu();
		if (choice == 0) {
			printf("goodbye\n");
			break;
		}
		else if (choice < 0 || choice > 7) {
			printf("你的输入有误,请重新输入\n");
			continue;
		}
		func[choice](&addressList);
		system("pause");
		system("cls");
		//Func func = func[choice]
		//func(&addressList)
	}
	system("pause");
	//当前这个数组的生命周期本就应该跟随整个程序,既然这个数组一直不需要用,就不能提前释放
	//当程序结束,内存会被系统自动回收
}

如果有什么问题,欢迎大家指出! 

C语言课程设计任务书(4) 一、题目:通讯录管理 二、目的与要求 1. 目的: (1)基本掌握面向过程程序设计的基本思路和方法; (2)达到熟练掌握C语言的基本知识和技能; (3)能够利用所学的基本知识和技能,解决简单的程序设计问题 2. 要求 基本要求: 1.         要求利用C语言面向过程的编程思想来完成系统的设计; 2.       突出C语言的函数特征,以多个函数实现每一个子功能; 3.         画出功能模块图; 4.         具有清晰的程序流程图和数据结构的详细定义; 5.       熟练掌握C语言对文件的各种操作。 创新要求: 在基本要求达到后,可进行创新设计,如系统用户功能控制,对管理员级和一般级别的用户系统功能操作不同 三、信息描述 有关该系统基本信息的描述,如:姓名、电话、城市和邮编等。 四、功能描述 1.       名单基本信息(姓名,城市,电话,邮编等)的录入,并存放在文件当中。 2.       基本信息的查询与修改。 3.       记录的添加和删除。 4.       对同一类型记录的查找:如查找同一城市的记录或同一省份的记录。 五、解决方案 1.       分析程序的功能要求,划分程序功能模块。 2.       画出系统流程图。 3.       代码的编写。定义数据结构和各个功能子函数。 4.       程序的功能调试。 5.       完成系统总结报告以及使用说明书 六、进度安排 此次课程设计时间为一周或两周,分四个阶段完成: 1.       分析设计阶段。指导教师应积极引导学生自主学习和钻研问题,明确设计要求,找出实现方法,按照需求分析、总体设计、详细设计这几个步骤进行。 2.       编码调试阶段:根据设计分析方案编写C代码,然后调试该代码,实现课题要求的功能。 3.       总结报告阶段:总结设计工作,写出课程设计说明书,要求学生写出需求分析、总体设计、详细设计、编码、测试的步骤和内容。 4.       考核阶段。 七、撰写课程设计报告或课程设计总结 课程设计报告要求: 总结报告包括需求分析、总体设计、详细设计、编码(详细写出编程步骤)、测试的步骤和内容、课程设计总结、参考资料等,不符合以上要求者,则本次设计以不及格记。 八、参考资料  《C语言程序设计教程》   网上相关资料(....略)
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值