学生通讯录管理系统【C语言】

说明

大一下学期开学第一个月末c语言课程设计————学生通讯录管理系统。本文意在记录4个月前的学习过程

课程内容

本次课程要求学生利用c语言代码设计一个学生通讯录管理系统并实现各种功能,如:1.添加、2.打印、3.查找、4.修改、5.删除通讯录、6.排序通讯录、7.保存等,并在实现功能的过程中磨练代码调试能力和加强对各类库函数的使用以及对结构体数组的认识和运用

设计思路

利用结构体数组实现对通讯录的“增删查改”等功能,先利用switch分支结构进行循环,再利用文件储存通讯录,最后利用不同的函数实现不同功能

系统环境

本程序可在c或c++环境下运行

完整代码

头文件:genshin.h

#define _CRT_SECURE_NO_WARNINGS 1.

#define MAX 50
#define MAX1 1000//宏定义,分别限定学生特征数组的大小和最大可存入的学生个数

#include<stdio.h>
#include<windows.h>
#include<stdlib.h>
#include<string.h>//头文件




typedef struct person //个人特征结构体
{
	char name[MAX];//名字
	char sex[MAX];//性别
	char age[MAX];//年龄
	char tele[MAX];//电话
	char addr[MAX];//住址
	char ID[MAX];//学号
}person;//自定义为person


typedef struct contact //通讯录结构体
{
	person num[MAX1];//结构体数组,结构体类型为person
	int size;        //数组下标,初始值为0,通过该下标可找到一共有多少个人在结构体数组内,以便后续实现各类功能
}contact;//自定义为contact



void menu();//声明菜单



enum select //枚举类型,以便switch选择,一目了然,代码可读性高
{
	EXIT,//0
	ADD,//1
	DELBYNAME,//2
	DELBYID,//3
	FINDBYNAME,//4
	FINDBYID,//5
	MODIFYBYNAME,//6
	MODIFYBYID,//7
	SORTBYNAME,//8
	SORTBYTELE,//9
	SORTBYID,//10
	PRINT//11
};

void InitContact(contact*a);//初始化

void save(contact* a, int sz);//保存

void AddContact(contact* a);//添加

void DelContact(contact* a);//删除,名字

void DelContactID(contact* a);//删除,学号

void findContact(contact* a);//查找,名字

void findContactID(contact* a);//查找,学号

void ModifyContact(contact*a);//修改,名字

void ModifyContactID(contact* a);//修改,学号

void SortContact(contact*a,int sz);//排序,名字

void SortContactByTele(contact* a, int sz);//排序,号码

void SortContactByID(contact* a, int sz);//排序,学号

void PrintContact(contact* a);//打印

主函数:genshin.c

#define _CRT_SECURE_NO_WARNINGS 1.

#include"3.h"//自定义的头文件



int main()
{
	int input = 0;
	contact A;//将通讯录结构体命名为A
	FILE* fp;//定义一个指向FILE类型的指针


	if ((fp=fopen("genshin.dat","r" ))!= NULL)//如果文件内容不为空,则写入通讯录结构体内
	{
		fscanf(fp, "%d",  &A.size);//从文件中写入存放的size,其代表的是存入人的个数

		for (int i = 0; i < A.size; i++)//循环写入各类特征
		{
			fscanf(fp, "%s%s%s%s%s%s", A.num[i].name, A.num[i].sex, A.num[i].age, A.num[i].tele, A.num[i].addr,A.num[i].ID);//顺序写入到person结构体中
		}
	}
	else
	{
		InitContact(&A);//若没有任何内容,则初始化为0
	}

	do
	{
		menu();//调用菜单
		scanf("%d", &input);//选择功能


		switch (input)
		{
		case EXIT:
			save(&A, A.size);//保存
			exit(0);//退出
		case ADD:
			AddContact(&A);//添加
			system("pause");
			system("cls");
			break;
		case DELBYNAME:
			DelContact(&A);//删除,姓名
			system("pause");
			system("cls");
			break;
		case DELBYID:
			DelContactID(&A);//删除,学号
			system("pause");
			system("cls");
			break;
		case FINDBYNAME:
			findContact(&A);//查找,名字
			system("pause");
			system("cls");
			break;
		case FINDBYID:
			findContactID(&A);//查找,学号
			system("pause");
			system("cls");
			break;
		case MODIFYBYNAME:
			ModifyContact(&A);//修改,名字
			system("pause");
			system("cls");
			break;
		case MODIFYBYID:
			ModifyContactID(&A);//修改,学号
			system("pause");
			system("cls");
			break;
		case SORTBYNAME:
			SortContact(&A,A.size);//排序,名字
			system("pause");
			system("cls");
			break;
		case SORTBYTELE:
			SortContactByTele(&A, A.size);//排序,号码
			system("pause");
			system("cls");
			break;
		case SORTBYID:
			SortContactByID(&A, A.size);//排序,学号
			system("pause");
			system("cls");
			break;
		case PRINT:
			PrintContact(&A);//打印
			system("pause");
			system("cls");
			break;
		default:
			printf("\n输入错误\n");//输入错误则提醒
			system("pause");
			system("cls");
			break;
		}
	} while (input);//循环

}

实现功能:impact.c

​
#define _CRT_SECURE_NO_WARNINGS 1.

#include"3.h"//自定义的头文件

void menu()//打印菜单
{
	printf("\n 0.退出保存\t1.添加内容\n\n 2.姓名删除\t3.学号删除\n\n 4.姓名查找\t5.学号查找\n\n 6.姓名修改\t7.学号修改\n\n 8.姓名排序\t9.电话排序\n\n10.学号排序    11.显示内容\n");
	printf("\n请选择:");
}

void InitContact(contact* a)//初始化
{
	a->size = 0;
	memset(a->num, 0, sizeof(a->num));
}


void AddContact(contact* a)//添加
{
	if (a->size == MAX1)//若size==MAX1,则内容已满
	{
		printf("\n内容已满,无法添加");
		return;
	}
	else
	{
		printf("\n输入名字:");
		scanf("%s", a->num[a->size].name);
		printf("\n输入性别:");
		scanf("%s", a->num[a->size].sex);
		printf("\n输入年龄:");
		scanf("%s", a->num[a->size].age);
		printf("\n输入电话:");
		scanf("%s", a->num[a->size].tele);
		printf("\n输入住址:");
		scanf("%s", a->num[a->size].addr);
		printf("\n输入学号:");
		scanf("%s", a->num[a->size].ID);      //scanf无法读取空格,导致输入时不能有空格输入,否则会导致后续输入出现问题,待解决


		a->size++;//每添加一个人就++一次

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


void save(contact*a,int sz)//保存
{
	int i;
	FILE* fp;//定义一个指向FILE的指针
	fp = fopen("genshin.dat", "w");//打开文件并写入
	fprintf(fp, "%d\n", sz);//写入size到文件中

	for (i = 0; i < sz; i++)
	{
		fprintf(fp, "%-10s\t%-5s\t%-5s\t%-15s\t%-20s\t", a->num[i].name, a->num[i].sex, a->num[i].age, a->num[i].tele, a->num[i].addr);
		fprintf(fp,"%-15s\n\n", a->num[i].ID);     //写入各类特征到文件中d
	}
}


//static限定该函数只能在2.c内使用
static int FindContact(const contact*a,char n[])//查找
{
	for (int i = 0; i < a->size; i++)//遍历结构体数组
	{
		if (strcmp(a->num[i].name,n)==0)//若返回值为0,则返回i,找到你要找的人在结构体数组中的下标
		{
			return i;
		}
		else if (strcmp(a->num[i].ID, n) == 0)//同理
		{
			return i;
		}
	}
	return -1;//找不到则返回-1
}



void DelContact(contact*a)//删除,名字
{
	char name[MAX] = { 0 };

	if (a->size == 0)//size为0则无内容
	{
		printf("\n无可删内容\n");
	}

	else
	{
		printf("\n请输入你要删除的人名字:");
		scanf("%s", name);

		if (FindContact(a, name)==-1)//调用查找函数
		{
			printf("\n没有这个人!\n");

			return;//返回至菜单
		}
		for (int i= FindContact(a, name); i < a->size-1;i++)//若找到了,则将该结构体数组用后面的内容覆盖,只覆盖到倒数第二个内容,防止越界
		{
			a->num[i] = a->num[i + 1];
		}

		a->size--;//每删除一个就减小一次结构体数组的下标

		printf("\n删除成功!\n\n");
	}
}

void DelContactID(contact* a)//删除,学号
{
	char ID[MAX] = { 0 };
	if (a->size == 0)
	{
		printf("\n无可删内容\n");
	}
	else
	{
		printf("\n请输入你要删除的人学号:");
		scanf("%s",ID);
		if (FindContact(a, ID) == -1)
		{
			printf("\n没有这个人!\n");
			return;
		}
		for (int i = FindContact(a,ID); i < a->size - 1; i++)
		{
			a->num[i] = a->num[i + 1];
		}
		a->size--;
		printf("\n删除成功!\n\n");
	}
}


void PrintContact(contact* a)//打印
{
	printf("\n%-10s\t%-5s\t%-5s\t%-15s\t%-20s\t", "名字", "性别", "年龄", "电话", "住址");
	printf("%-15s\n\n", "学号");                                                           //对齐打印
	for (int i = 0; i < a->size; i++)
	{
		printf("%-10s\t%-5s\t%-5s\t%-15s\t%-20s\t", a->num[i].name, a->num[i].sex, a->num[i].age, a->num[i].tele, a->num[i].addr);
		printf("%-15s\n\n", a->num[i].ID);                                                  //对齐打印
	}
}



void findContact(contact* a)//查找,名字
{
	char name[MAX] = { 0 };
	printf("请输入你要查找的人的名字:");
	scanf("%s", name);

	if (FindContact(a, name) == -1)//调用查找函数
	{
		printf("\n没有这个人!\n");
		return;
	}

	else
	{
		int i = FindContact(a, name);
		//打印
		printf("\n%-10s\t%-5s\t%-5s\t%-15s\t%-20s\t", "名字", "性别", "年龄", "电话", "住址");
		printf("%-15s\n\n", "学号");
		printf("%-10s\t%-5s\t%-5s\t%-15s\t%-20s\t", a->num[i].name, a->num[i].sex, a->num[i].age, a->num[i].tele, a->num[i].addr);
		printf("%-15s\n\n", a->num[i].ID);
	}
}


void findContactID(contact* a)//查找,学号
{

	char ID[MAX] = { 0 };
	printf("请输入你要查找的人的学号:");
	scanf("%s", ID);
	if (FindContact(a, ID) == -1)//调用
	{
		printf("\n没有这个人!\n");
		return;
	}
	else
	{
		int i = FindContact(a, ID);
		//打印
		printf("\n%-10s\t%-5s\t%-5s\t%-15s\t%-20s\t", "名字", "性别", "年龄", "电话", "住址");
		printf("%-15s\n\n", "学号");
		printf("%-10s\t%-5s\t%-5s\t%-15s\t%-20s\t", a->num[i].name, a->num[i].sex, a->num[i].age, a->num[i].tele, a->num[i].addr);
		printf("%-15s\n\n", a->num[i].ID);
	}
}

void ModifyContact(contact*a)//修改,名字
{

	char name[MAX] = { 0 };
	char sex[MAX] = { 0 };
	char age[MAX] = { 0 };
	char tele[MAX] = { 0 };
	char addr[MAX] = { 0 };
	char id[MAX] = { 0 };
	printf("\n请输入你要修改的人的名字:");
	scanf("%s", name);

	if (FindContact(a, name) == -1)//先找有没有这个人
	{
		printf("\n没有这个人!\n");
		return;//无则返回至菜单
	}

	//有则修改
	else
	{
		int i = FindContact(a, name);//i为返回的数组下标
		printf("\n输入名字:");
		scanf("%s", a->num[i].name);
		printf("\n输入性别:");
		scanf("%s", a->num[i].sex);
		printf("\n输入年龄:");
		scanf("%s", a->num[i].age);
		printf("\n输入电话:");
		scanf("%s", a->num[i].tele);
		printf("\n输入住址:");
		scanf("%s", a->num[i].addr);
		printf("\n输入学号:");
		scanf("%s", a->num[i].ID);
		printf("\n修改成功!\n\n");
	}
}


void ModifyContactID(contact* a)//修改,学号
{

	char name[MAX] = { 0 };
	char sex[MAX] = { 0 };
	char age[MAX] = { 0 };
	char tele[MAX] = { 0 };
	char addr[MAX] = { 0 };
	char id[MAX] = { 0 };
	printf("\n请输入你要修改的人的学号:");
	scanf("%s", id);
	if (FindContact(a, id) == -1)
	{
		printf("\n没有这个人!\n");
		return;
	}
	else
	{
		int i = FindContact(a, id);
		printf("\n输入名字:");
		scanf("%s", a->num[i].name);
		printf("\n输入性别:");
		scanf("%s", a->num[i].sex);
		printf("\n输入年龄:");
		scanf("%s", a->num[i].age);
		printf("\n输入电话:");
		scanf("%s", a->num[i].tele);
		printf("\n输入住址:");
		scanf("%s", a->num[i].addr);
		printf("\n输入学号:");
		scanf("%s", a->num[i].ID);
		printf("\n修改成功!\n\n");
		}
}



void SortContact(contact* a,int sz)//排序,名字
{

	person t;//创建一个person类型的结构体t用于暂时储存要交换的结构体
	//选择法排序
	for (int i = 0; i < sz - 1; i++)
	{
		for (int j = i + 1; j < sz; j++)
			if (strcmp(a->num[i].name, a->num[j].name) > 0)
			{
				t = a->num[i];
				a->num[i] = a->num[j];
				a->num[j] = t;
			}
	}
	//打印
	printf("\n%-10s\t%-5s\t%-5s\t%-15s\t%-20s\t", "名字", "性别", "年龄", "电话", "住址");
	printf("%-15s\n\n", "学号");

	for (int i = 0; i < a->size; i++)
	{
		printf("%-10s\t%-5s\t%-5s\t%-15s\t%-20s\t", a->num[i].name, a->num[i].sex, a->num[i].age, a->num[i].tele, a->num[i].addr);
		printf("%-15s\n\n", a->num[i].ID);
	}
	printf("\n姓名升序成功\n");
}

void SortContactByTele(contact* a, int sz)//排序,号码
{

	person t;
	//冒泡排序
	for (int i = 0; i < sz - 1; i++)
	{
		for (int j = 0; j < sz - 1 - i; j++)
			if (strcmp(a->num[j].tele, a->num[j + 1].tele) > 0)
			{
				t = a->num[j];
				a->num[j] = a->num[j + 1];
				a->num[j + 1] = t;
			}
	}

	printf("\n%-10s\t%-5s\t%-5s\t%-15s\t%-20s\t", "名字", "性别", "年龄", "电话", "住址");
	printf("%-15s\n\n", "学号");

	for (int i = 0; i < a->size; i++)
	{
		printf("%-10s\t%-5s\t%-5s\t%-15s\t%-20s\t", a->num[i].name, a->num[i].sex, a->num[i].age, a->num[i].tele, a->num[i].addr);
		printf("%-15s\n\n", a->num[i].ID);
	}
	printf("\n号码升序成功\n");
}

void SortContactByID(contact* a, int sz)//排序,学号
{

	person t;
	//冒泡排序
	for (int i = 0; i < sz - 1; i++)
	{
		for (int j = 0; j < sz - 1 - i; j++)
			if (strcmp(a->num[j].ID, a->num[j + 1].ID) > 0)
			{
				t = a->num[j];
				a->num[j] = a->num[j + 1];
				a->num[j + 1] = t;
			}
	}

	printf("\n%-10s\t%-5s\t%-5s\t%-15s\t%-20s\t", "名字", "性别", "年龄", "电话", "住址");
	printf("%-15s\n\n", "学号");

	for (int i = 0; i < a->size; i++)
	{
		printf("%-10s\t%-5s\t%-5s\t%-15s\t%-20s\t", a->num[i].name, a->num[i].sex, a->num[i].age, a->num[i].tele, a->num[i].addr);
		printf("%-15s\n\n", a->num[i].ID);
	}
	printf("\n学号升序成功\n");
}

​

程序测试

本程序界面简洁,功能较完善

1.添加内容 

  每个功能结束后都会清空屏幕并返回菜单,如下图

2 删除功能  

本功能提供了两种删除方式,使用者可通过学号和名字进行删除。

3.查找功能

本功能同样可通过两种方式查找。

4.修改功能
 

通过名字或学号来找到你要修改的人,若未找到,本程序会提示,并返回菜单,若找到,则修改内容。 

5.排序功能 

本程序可通过三种方式排序,即姓名首字母大小,电话号码数字大小与学号大小,排序方式为升序,从小到大依次向下排列。

 
6.打印与保存

每次完成功能后,我们可以通过打印功能来检测是否成功实现,而在你不需要更改通讯录时,按数字0退出通讯录,程序会在退出的同时保存内容。

可优化的内容

1.本程序在输入时scanf并不能读取空格,会导致后续输入错误

2.本程序功能不够完善,查找,删除,修改时未考虑同名的情况,排序时未提供升降序的选择

3.程序的可读性仍有待提高并且存在代码冗余的情况

4.本程序在保存时必须按0退出并保存,直接关闭程序并不能起到保存的效果

5.等等等等

原创声明

郑重声明:本文内容是由作者本人独立完成的。有关观点、方法、数据和文献等的引用已在文中指出。除文中已注明引用的内容外,本报告不包含任何其他个人或集体已经公开发表的作品成果,不存在剽窃、抄袭行为。

特此声明!

设计一个《学生通讯录管理系统》,在动态链表程序的基础上,设计要求如下 (必须使用结构体和链表等数据结构) 1建立文件 存储文件使用指定文件名或默认文件名; 可以不保存输入记录,但需要确认是否保存输入记录 如果已有文件,只能在其后追加; 新增记录可以不存入原文件中,以可以用原来的文件覆盖内存的内容; 可以将多个个文件记录合并到一个文件中; 2文件的存取和显示 可以单独存取文件; 可以随时显示内存中记录的全部内容; 可以直接存取默认文件或指定文件; 3删除记录 可以按“姓名”或“电话”方式删除记录并更新内存链表内容; 能给出被删除的信息,输出没有找到的信息; 如果已经是空表,上出时应给出信息并返回主菜单; 如果没有要删除的信息,输出没有找到的信息; 删除操作仅限于内存,只有执行记录时,才能覆盖原记录; 4查询记录 可以按“姓名”或“电话”或“宿舍”方式查询记录 能给出查询记录的信息; 如果查询的信息不存在,输出没有找到的信息; 5 整体功能 a可以随时检索、删除、或增加新记录,保存或取消新的记录 b使姓名可由16位字符和数字的混合编码组成 c使电话号码可由18位字符和数字组成 d将输出信息加上输出信息信息栏,例如 姓名 电话 性别 年龄 生日 宿舍 李四 1234 男 21 7月1日 东二333 e使用菜单实现功能的正确的选择 f 所有节点信息都是动态生成。 6测试程序 应列出测试大纲对程序进行测试; 应保证测试用例测试到程序的各种边缘情况
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值