【C语言】解决学校管理系统大作业(增删查改)——学会通讯录(文件版)

文章介绍了一个通讯录管理系统的演变,从大数组到动态内存,再到3.0版本,新增了信息保存和加载功能。系统实现了添加、删除、查询、修改、排序等操作,并详细给出了代码实现,包括内存扩容、文件读写等关键函数。
摘要由CSDN通过智能技术生成

目录

 前言

整段代码

类型的定义及函数的声明(头文件)

主体框架

函数的实现 

相较于动态内存版本的新增内容 

通讯录信息保存函数

文件加载函数 

总结


 前言

通讯录更新到3.0了!!!通讯录1.0是大数组版本,缺点是内存按需分配,通讯录2.0是动态内存版本,缺点是不能保存信息,现在这一版,完善了前两版的缺点。整体的实现思路请看我大数组版通讯录的博客https://blog.csdn.net/ZHENGZJM/article/details/128511139?spm=1001.2014.3001.5501icon-default.png?t=MBR7https://blog.csdn.net/ZHENGZJM/article/details/128511139?spm=1001.2014.3001.5501

整段代码

类型的定义及函数的声明(头文件)

#define _CRT_SECURE_NO_WARNINGS
#pragma once
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
//重定义最大名字,最大性别,最大电话,最大
#define MAX_NAME 100
#define MAX_SEX 100
#define MAX_TELE 100
#define MAX_PERSON 1000
#define MAX_ADDRESS 100
#define default_len 1
#define default_inc 2 
//定以个人信息结构体
typedef struct perinf
{
	char name[MAX_NAME];
	char sex[MAX_SEX];
	char tele[MAX_TELE];
	char address[MAX_ADDRESS];
	int age;
}perinf;
//定义通讯录类型
typedef struct contact
{
	perinf* arr;
	int sz;
	int num;
}contact;
//定义菜单枚举类型
enum menu
{
	EXIT,
	ADD,
	DEL,
	SEEK,
	MODIFY,
	SORT,
	DISPLAY
};
//定义查找内的菜单枚举类型
enum menu_seek
{
	EXIT1,
	NAME,
	SEX,
	TELE,
	ADDRESS,
	AGE
};
//定义排序菜单枚举类型
enum menu_sort
{
	EXIT2,
	SORTBYNAME,
	SORTBYAGE
};
//声明打印菜单函数
void menu_print();
//声明菜单选择函数
void menu_option(int input, contact* p1);
//声明初始化通讯录函数
void Init_contact(contact* p1);
//声明添加联系人函数
void perinf_add(contact* p1);
//声明删除联系人函数
void perinf_del(contact* p1);
//声明遍历对比函数
int perinf_seek(contact* p1);
//声明查询函数
void perinf_SEEK(contact* p1);
//声明查找内的菜单函数
void menu_seek();
//声明查找内的菜单选择函数
void seekmenu_option(int a, int ret, contact* p1);
//声明修改函数
void perinf_MODIFY(contact* p1);
//声明显示通讯录函数
void perinf_dispay(contact* p1);
//声明排序菜单选择函数
void sortmenu_option(int a, contact* p1);
//声明排序菜单函数
void menu_sort();
//声明排序函数
void perinf_sort(contact* p1);
//扩容函数的声明
void capacity_expansion(contact* p1);
//销毁函数的声明
void Destroy(contact* p1);
//声明通讯录保存函数
void contact_save(contact* p1);
//声明加载函数
void load_file(contact* p1);

主体框架

打印菜单》用户选择》用户选择的实现,以及实现多次操作。

#define _CRT_SECURE_NO_WARNINGS
#include"contact.h"
int main()
{
	contact con;
	Init_contact(&con);
	int input = 0;
	do
	{
		//打印菜单
		menu_print();
		printf("请选择您需要的功能:>\n");
		scanf("%d", &input);
		menu_option(input, &con);
	} while (input);
	return 0;
}

函数的实现 

#include"contact.h"
//扩容函数
void capacity_expansion(contact* p1) 
{
	perinf* tmp = (perinf*)realloc(p1->arr, (p1->num+default_inc)* sizeof(perinf));
	if (tmp != NULL)
	{
		p1->arr = tmp;
		p1->num+=2;
		printf("扩容成功!\n");
	}
	else
	{
		printf("扩容失败\n");
	}
}
//声明加载函数
void load_file(contact* p1)
{
	FILE* p = fopen("member_message.txt", "r");
	if (p == NULL)
	{
		perror("fopen");
		return;
	}
	else
	{
		perinf tmp = { 0 };
		while (fread(&p1->arr[p1->sz], sizeof(perinf), 1, p))
		{
			capacity_expansion(p1);
			p1->sz++;
		}
	}
	fclose(p);
	p = NULL;
}
//销毁函数
void Destroy(contact* p1)
{
	free(p1->arr);
	p1->arr = NULL;
	p1->sz = 0;
	p1->num = 0;
}
//初始化函数
void Init_contact(contact* p1)
{
	perinf* tmp= (perinf*)malloc(default_len *sizeof(perinf));
	if (tmp != NULL)
	{
		p1->arr = tmp;
	}
	else
	{
		printf("初始化内存开辟失败,请调整默认值");
	}
	p1->num = default_len;
	p1->sz = 0;
	//加载文件
	load_file(p1);
}
//打印菜单函数
void menu_print()
{
	printf("-------------------------------------\n");
	printf("=====================================\n");
	printf("=========1.添加      2.删除==========\n");
	printf("=========3.查询      4.修改==========\n");
	printf("=========5.排序      6.显示通讯录====\n");
	printf("=========      0.退出      ==========\n");
	printf("=====================================\n");
	printf("-------------------------------------\n");
}
//查找内的菜单函数
void menu_seek()
{
	printf("请选择要修改的内容\n");
	printf("-------------------------------------\n");
	printf("=====================================\n");
	printf("=========1.姓名      2.性别==========\n");
	printf("=========3.电话号码  4.家庭住址======\n");
	printf("=========5.年龄      0.退出修改======\n");
	printf("=====================================\n");
	printf("-------------------------------------\n");
}
//查找内的菜单选择函数
void seekmenu_option(int a, int ret, contact* p1)
{
	switch (a)
	{
	case NAME:
		printf("请输入新姓名\n");
		scanf("%s", p1->arr[ret].name);
		printf("修改成功\n");
		break;
	case SEX:
		printf("请输入新性别\n");
		scanf("%s", p1->arr[ret].sex);
		printf("修改成功\n");
		break;
	case TELE:
		printf("请输入新电话号码\n");
		scanf("%s", p1->arr[ret].tele);
		printf("修改成功\n");
		break;
	case ADDRESS:
		printf("请输入新家庭住址\n");
		scanf("%s", p1->arr[ret].address);
		printf("修改成功\n");
		break;
	case AGE:
		printf("请输入新年龄\n");
		scanf("%d", &p1->arr[ret].age);
		printf("修改成功\n");
		break;
	case EXIT1:
		printf("退出修改\n");
		break;
	default:
		printf("请选择正确的选项\n");
		break;
	}
}
//菜单选择函数
void menu_option(int input, contact* p1)
{
	switch (input)
	{
	case ADD:
		system("cls");
		printf("添加联系人\n");
		perinf_add(p1);
		break;
	case DEL:
		system("cls");
		printf("删除联系人\n");
		perinf_del(p1);
		break;
	case SEEK:
		system("cls");
		printf("查询联系人\n");
		perinf_SEEK(p1);
		break;
	case MODIFY:
		system("cls");
		printf("修改联系人信息\n");
		perinf_MODIFY(p1);
		break;
	case SORT:
		system("cls");
		printf("通讯录排序\n");
		perinf_sort(p1);
		break;
	case DISPLAY:
		system("cls");
		printf("显示通讯录\n");
		perinf_dispay(p1);
		break;
	case EXIT:
		system("cls");
		contact_save(p1);
		Destroy(p1);
		printf("退出成功,感谢使用。\n祝您生活美满,家庭幸福,身体健康\n");
		break;
	default:
		printf("请重新选择正确的选项");
		break;
	}
}
//用户添加函数
void perinf_add(contact* p1)
{
	if (p1->sz == p1->num)
	{
		capacity_expansion(p1);
	}
	printf("请输入姓名:>\n");
	scanf("%s", p1->arr[p1->sz].name);
	printf("请输入性别:>\n");
	scanf("%s", p1->arr[p1->sz].sex);
	printf("请输入电话号码:>\n");
	scanf("%s", p1->arr[p1->sz].tele);
	printf("请输入年龄:>\n");
	scanf("%d", &(p1->arr[p1->sz].age));
	printf("请输入家庭住址:>\n");
	scanf("%s", p1->arr[p1->sz].address);
	p1->sz++;
	printf("添加成功QvQ\n");
	return;
}
//查找函数
int perinf_seek(contact* p1)
{
	int i = 0;
	char brr[MAX_NAME] = { 0 };
	perinf_dispay(p1);
	printf("请输入要操作的人名:>\n");
	scanf("%s", brr);
	//遍历查找人名
	for (i = 0; i < p1->sz; i++)
	{
		if ((strcmp(p1->arr[i].name, brr) == 0))
		{
			return i;
		}
	}
	return -1;
}
//删除函数
void perinf_del(contact* p1)
{
	if (p1->sz == 0)
	{
		printf("当前通讯录尚未存入联系人,无法删除\n");
		return;
	}
	int ret = perinf_seek(p1);
	if (ret == -1)
	{
		printf("查无此人,无法删除\n");
		return;
	}
	else
	{
		memmove(&(p1->arr[ret]), &(p1->arr[ret + 1]), (long long)(p1->sz - ret) * sizeof(p1->arr[0]));
		printf("删除成功\n");
		p1->sz--;
		return;
	}
}
//查询函数
void perinf_SEEK(contact* p1)
{
	int ret = perinf_seek(p1);
	if (ret == -1)
	{
		printf("查无此人\n");
		return;
	}
	else
	{
		printf("%-20s\t%-20s\t%-20s\t%-20s\t%-20s\n", "姓名", "性别", "电话号码", "家庭住址", "年龄");
		printf("%-20s\t%-20s\t%-20s\t%-20s\t%-20d\n", p1->arr[ret].name, p1->arr[ret].sex, p1->arr[ret].tele, p1->arr[ret].address, p1->arr[ret].age);
		return;
	}
}
//修改函数
void perinf_MODIFY(contact* p1)
{
	int ret = perinf_seek(p1);
	if (ret == -1)
	{
		printf("查无此人\n");
		return;
	}
	else
	{
		int a = 0;
		do
		{
			menu_seek();
			scanf("%d", &a);
			seekmenu_option(a, ret, p1);
		} while (a);

	}
}
//显示整个通讯录函数
void perinf_dispay(contact* p1)
{
	int i = 0;
	printf("%-20s\t%-20s\t%-20s\t%-20s\t%-20s\n", "姓名", "性别", "电话号码", "家庭住址", "年龄");
	for (i = 0; i < p1->sz; i++)
	{
		printf("%-20s\t%-20s\t%-20s\t%-20s\t%-20d\n", p1->arr[i].name, p1->arr[i].sex, p1->arr[i].tele, p1->arr[i].address, p1->arr[i].age);
	}
}
//排序函数
void perinf_sort(contact* p1)
{
	int a = 0;
	menu_sort();
	printf("请选择排序方式\n");
	scanf("%d", &a);
	sortmenu_option(a, p1);
	printf("排序完成\n");
}
//排序菜单函数
void menu_sort()
{
	printf("请选择要修改的内容\n");
	printf("-------------------------------------\n");
	printf("=====================================\n");
	printf("===1.按名字排序       2.按年龄排序===\n");
	printf("===          0.退出排序           ===\n");
	printf("-------------------------------------\n");
}
//排序菜单选择函数
void sortmenu_option(int a, contact* p1)
{
	int i = 0; int j = 0;
	perinf tmp;
	switch (a)
	{
	case SORTBYNAME:
		for (i = 0; i < p1->sz; i++)
		{
			for (j = 0; j < p1->sz - 1; j++)
			{
				if (strcmp(p1->arr[j].name, p1->arr[j + 1].name) > 0)
				{
					tmp = p1->arr[j + 1];
					p1->arr[j + 1] = p1->arr[j];
					p1->arr[j] = tmp;
				}
			}
		}
		break;
	case SORTBYAGE:
		for (i = 0; i < p1->sz; i++)
		{
			for (j = 0; j < p1->sz - 1; j++)
			{
				if (p1->arr[j].age > p1->arr[j + 1].age)
				{
					tmp = p1->arr[j + 1];
					p1->arr[j + 1] = p1->arr[j];
					p1->arr[j] = tmp;
				}
			}
		}
		break;
	case EXIT2:
	{
		printf("退出排序\n");
	}
	break;
	default:
		printf("请选择正确的选项\n");
		break;
	}
}
//通讯录保存函数
void contact_save(contact* p1)
{
	int i = 0;
	FILE* p=fopen("member_message.txt", "w");
	if (p == NULL)
	{
		perror("fopen");
		return;
	}
	else
	{
		for (i = 0; i < p1->sz; i++)
		{
			fwrite(p1->arr+i, sizeof(perinf),1, p);
		}
		fclose(p);
		p = NULL;
	}
	printf("保存成功\n");
}

相较于动态内存版本的新增内容 

通讯录信息保存函数

先打开文件,用“w”的原因是有则写入并且会覆盖掉原内容,无则创建再写入,先进行判断是否成功打开文件,然后使用fwrite进行写入。

//通讯录保存函数
void contact_save(contact* p1)
{
	int i = 0;
	FILE* p=fopen("member_message.txt", "w");
	if (p == NULL)
	{
		perror("fopen");
		return;
	}
	else
	{
		for (i = 0; i < p1->sz; i++)
		{
			fwrite(p1->arr+i, sizeof(perinf),1, p);
		}
		fclose(p);
		p = NULL;
	}
	printf("保存成功\n");
}

文件加载函数 

先打开文件并判断是否打开成功,然后利用fread函数进行读取,因为开始通讯录成员为零,记录通讯录成员的sz便也为零,随着信息的读入,sz会增加,这就需要判断要不要扩容,也就是用capactity_expansion函数来判断需不需要扩容,每读入一个信息sz就加一。

//加载函数
void load_file(contact* p1)
{
	FILE* p = fopen("member_message.txt", "r");
	if (p == NULL)
	{
		perror("fopen");
		return;
	}
	else
	{
		perinf tmp = { 0 };
		while (fread(&p1->arr[p1->sz], sizeof(perinf), 1, p))
		{
			capacity_expansion(p1);
			p1->sz++;
		}
	}
	fclose(p);
	p = NULL;
}

总结

 学校的管理系统大作业,本质就是实现增删查改,而通讯录也是需要增删查改的,所以说学会了通讯录就能轻松完成学校的管理系统大作业~希望能帮助到同志们。最终版本应该是用数据库的版本,等我再学完了之后再写博客

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值