双向循环链表实现—通讯录(学生管理系统,自行车管理系统,影院管理系统)—C语言课设(万能模板)—数据结构—用文件存储数据

大家好,如果觉得我这篇文章写的不错并且对你有帮助的话就关注一下呗。
这是我关于双向循环链表的博客,可以点进去康康啦
编译器是VS2019,依旧是分为三个文件
我先把三个文件的原码放出来,然后对于函数 一 一 解释。

申请空间

struct Contact* BuyNewNode(char* name, int age, char* sex, char* tel, char* adr)
{
	struct Contact* newnode = (struct Contact*)malloc(sizeof(struct Contact));
	assert(newnode);
	newnode->next = newnode;
	newnode->front = newnode;
	strcpy(newnode->name , name);
	newnode->age = age;
	strcpy(newnode->sex , sex);
	strcpy(newnode->tel , tel);
	strcpy(newnode->adr , adr);
	return newnode;
}

先将文件中的数据存到链表中

这里用 feof判断文件光标后面是否有内容,如果光标后面没有内容则返回非0,如果有内容则返回0,党光标后面有内容的时候我们需要读取文件,所以循环条件为 while(!feof)

void SaveFileData(PC*phead)
{
	
	FILE* fp = fopen("data.txt", "r");
	assert(phead);
	if (fp == NULL)
	{
		printf("%s", strerror(errno));
		return;
	}
	getc(fp);
	if (!feof(fp))
	{
		rewind(fp);
	}
	while (!feof(fp))
	{
		
		PC* newnode = BuyNewNode("000000", 0, "000000", "00000", "000000");
		fscanf(fp, "%s ", newnode->name);
		fscanf(fp, "%d ", &(newnode->age));
		fscanf(fp, "%s ", newnode->sex);
		fscanf(fp, "%s ", newnode->tel);
		fscanf(fp, "%s ", newnode->adr);
		PC* head = phead->front;
		head->next = newnode;
		newnode->front = head;
		newnode->next = phead;
		phead->front = newnode;
	}
	fclose(fp);
	fp = NULL;
}

1.添加联系人

void ADDPc(PC* phead)
{
	PC* newnode = BuyNewNode("000000", 0, "000000", "00000", "000000");
	assert(phead);
	assert(newnode);
	printf("请输入姓名\n");
	scanf("%s", newnode->name);
	printf("请输入年龄\n");
	scanf("%d", &(newnode->age));
	printf("请输入性别\n");
	scanf("%s", newnode->sex);
	printf("请输入电话\n");
	scanf("%s", newnode->tel);
	printf("请输入地址\n");
	scanf("%s", newnode->adr);
	PC* head = phead->front;
	head->next = newnode;
	newnode->front = head;
	newnode->next = phead;
	phead->front = newnode;	
	printf("添加成功\n");
}

2.删除联系人

void DelPc(PC* pos)
{
	assert(pos);
	PC* Front = pos->front;
	PC* Next = pos->next;
	Front->next = Next;
	Next->front = Front;
	free(pos);
	pos = NULL;
}

3.查找联系人

PC* Find_by_name( PC* phead, char* name)
{
	assert(phead);
	PC* pos = phead->next;
	while (pos !=phead)
	{
		if (0 == strcmp(name, pos->name))
		{
			return pos;
		}
		pos = pos->next;
	}
	return NULL;
}

4.修改联系人

void MoDify(PC* pos)
{
	char str_name2[NAM_MAX] = "0";
	char str_sex2[SEX_MAX] = "0";
	char str_tel2[TEL_MAX] = "0";
	char str_adr2[ADR_MAX] = "0";
	assert(pos);

	printf("请输入新的姓名\n");
	scanf("%s", str_name2);
	strcpy(pos->name, str_name2);

	printf("请输入新的年龄\n");
	scanf("%d", &(pos->age));

	printf("请输入新的性别\n");
	scanf("%s", str_sex2);
	strcpy(pos->sex, str_sex2);

	printf("请输入新的电话\n");
	scanf("%s",str_tel2);
	strcpy(pos->tel, str_tel2);

	printf("请输入新的地址\n");
	scanf("%s", str_adr2);
	strcpy(pos->adr, str_adr2);
	
}

5.显示所有联系人

void Print(PC* phead)
{
	PC* cur = phead->next;
	assert(phead);
	if (cur == phead)
	{
		printf("还没有添加信息\n");
	}
	printf("姓名            年龄    性别    电话            地址\n");
	while (cur != phead)
	{
		printf("%-15s\t%-5d\t%-5s\t%-15s\t%-10s\n", cur->name, cur->age, cur->sex, cur->tel, cur->adr);
		cur = cur->next;
	}
}

6.清空所有联系人

void DesTroy(PC* phead)
{
	assert(phead);
	PC* cur=phead->next;
	while (cur != phead)
	{
		PC* Next = cur->next;
		free(cur);
		cur = Next;
	}
	phead->next = phead;
	phead->front = phead;
}

7.按名字排序所有联系人

由于qsort是用于一个连续的空间,所以,这里用冒泡排序。
算个数的时候要加上phead,但是排序的时候不要排phead

void Compare_ByName(PC*phead)
{
	int i =0;
	int j = 0;
	PC* cur = phead->next;
	PC* Next = cur->next;
	char Name_s[NAM_MAX] = "0";
	int age_s=0;
	char sex_s[SEX_MAX] = "0";
	char tel_s[TEL_MAX] = "0";
	char adr_s[ADR_MAX] = "0";
	assert(phead);

	for (i = 0; i < Size(phead)+1; i++)
	{
		for (j = 0; j < Size(phead) - i ;j++)
		{
			if ((strcmp(cur->name, Next->name) > 0) && (cur != phead) && (Next != phead))
			{
				strcpy(Name_s, cur->name);
				strcpy(cur->name, Next->name);
				strcpy(Next->name, Name_s);

				age_s = cur->age;
				cur->age = Next->age;
				Next->age = age_s;

				strcpy(sex_s, cur->sex);
				strcpy(cur->sex, Next->sex);
				strcpy(Next->sex, sex_s);

				strcpy(tel_s, cur->tel);
				strcpy(cur->tel, Next->tel);
				strcpy(Next->tel, tel_s);

				strcpy(adr_s, cur->adr);
				strcpy(cur->adr, Next->adr);
				strcpy(Next->adr, adr_s);
			}
			cur = cur->next;
			Next = Next->next;
		}
	}
}

8.将数据保存在文件中

void SaveData(PC* phead)
{
	FILE* fp = NULL;
	PC* cur = phead->next;
	assert(phead);
	fp = fopen("data.txt", "w");
	if (fp == NULL)
	{
		printf("%s", strerror(errno));
		return;
	}
	while (cur != phead)
	{
		fprintf(fp, "%s ", cur->name);
		fprintf(fp, "%d ", cur->age);
		fprintf(fp, "%s ", cur->sex);
		fprintf(fp, "%s ",  cur->tel);
		fprintf(fp, "%s ", cur->adr);
		fprintf(fp, "\n");//换行
		cur = cur->next;
	}
	fclose(fp);
	fp = NULL;
}

双向循环链表实现—通讯录(学生管理系统,自行车管理系统,影院管理系统)—C语言课设(万能模板)—数据结构—用文件存储数据_第1张图片
contact.h文件中包含所需要的头文件以及函数的声明:

contact.h文件

以下就是contact.h的内容

#pragma once
#include
#include
#include
#include
#include
#include

#define NAM_MAX 20
#define SEX_MAX 10
#define TEL_MAX 20
#define ADR_MAX 20

typedef struct Contact
{
	struct Contact* front;
	char name[NAM_MAX];
	int age;
	char sex[SEX_MAX];
	char tel[TEL_MAX];
	char adr[ADR_MAX];
	struct Contact* next;
}PC;

//申请空间√
PC* BuyNewNode(char* name, int age, char* sex, char* tel, char* adr);
void ADDPc(PC* phead);//增加联系人√
void DelPc(PC* pos);//删除联系人√
PC* Find_by_name(PC* phead,char* name);//通过姓名寻找联系人√
void Print(const PC* phead);//打印联系人√
void DesTroy(PC* phead);//销毁通讯录√
void MoDify(PC* pos);//修改联系人信息√
int Size(PC* phead);//计算数据数量√
void Compare_ByName(PC*phead);//按名字排序 abcdefg......√
void SaveData(PC*phead);// 保存数据√
void SaveFileData(PC*phead);//先将文件中的数据存到链表中√

contac.c是每个函数的实现:

contac.c文件

#define _CRT_SECURE_NO_WARNINGS 1
#include"contact.h"
struct Contact* BuyNewNode(char* name, int age, char* sex, char* tel, char* adr)
{
	struct Contact* newnode = (struct Contact*)malloc(sizeof(struct Contact));
	assert(newnode);
	newnode->next = newnode;
	newnode->front = newnode;
	strcpy(newnode->name , name);
	newnode->age = age;
	strcpy(newnode->sex , sex);
	strcpy(newnode->tel , tel);
	strcpy(newnode->adr , adr);
	return newnode;
}
void SaveFileData(PC*phead)
{
	
	FILE* fp = fopen("data.txt", "r");
	assert(phead);
	if (fp == NULL)
	{
		printf("%s", strerror(errno));
		return;
	}
	getc(fp);
	while (!feof(fp))
	{
		rewind(fp);
		PC* newnode = BuyNewNode("000000", 0, "000000", "00000", "000000");
		fscanf(fp, "%s ", newnode->name);
		fscanf(fp, "%d ", &(newnode->age));
		fscanf(fp, "%s ", newnode->sex);
		fscanf(fp, "%s ", newnode->tel);
		fscanf(fp, "%s ", newnode->adr);
		PC* head = phead->front;
		head->next = newnode;
		newnode->front = head;
		newnode->next = phead;
		phead->front = newnode;
	}
	fclose(fp);
	fp = NULL;
}
void Print(PC* phead)
{
	PC* cur = phead->next;
	assert(phead);
	if (cur == phead)
	{
		printf("还没有添加信息\n");
	}
	printf("姓名            年龄    性别    电话            地址\n");
	while (cur != phead)
	{
		printf("%-15s\t%-5d\t%-5s\t%-15s\t%-10s\n", cur->name, cur->age, cur->sex, cur->tel, cur->adr);
		cur = cur->next;
	}
}
void ADDPc(PC* phead)
{
	PC* newnode = BuyNewNode("000000", 0, "000000", "00000", "000000");
	assert(phead);
	assert(newnode);
	printf("请输入姓名\n");
	scanf("%s", newnode->name);
	printf("请输入年龄\n");
	scanf("%d", &(newnode->age));
	printf("请输入性别\n");
	scanf("%s", newnode->sex);
	printf("请输入电话\n");
	scanf("%s", newnode->tel);
	printf("请输入地址\n");
	scanf("%s", newnode->adr);
	PC* head = phead->front;
	head->next = newnode;
	newnode->front = head;
	newnode->next = phead;
	phead->front = newnode;	
	printf("添加成功\n");
}
PC* Find_by_name( PC* phead, char* name)
{
	assert(phead);
	PC* pos = phead->next;
	while (pos !=phead)
	{
		if (0 == strcmp(name, pos->name))
		{
			return pos;
		}
		pos = pos->next;
	}
	return NULL;
}
void DelPc(PC* pos)
{
	assert(pos);
	PC* Front = pos->front;
	PC* Next = pos->next;
	Front->next = Next;
	Next->front = Front;
	free(pos);
	pos = NULL;
}
void DesTroy(PC* phead)
{
	assert(phead);
	PC* cur=phead->next;
	while (cur != phead)
	{
		PC* Next = cur->next;
		free(cur);
		cur = Next;
	}
	free(phead);
	phead = NULL;
}
void MoDify(PC* pos)
{
	char str_name2[NAM_MAX] = "0";
	char str_sex2[SEX_MAX] = "0";
	char str_tel2[TEL_MAX] = "0";
	char str_adr2[ADR_MAX] = "0";
	assert(pos);

	printf("请输入新的姓名\n");
	scanf("%s", str_name2);
	strcpy(pos->name, str_name2);

	printf("请输入新的年龄\n");
	scanf("%d", &(pos->age));

	printf("请输入新的性别\n");
	scanf("%s", str_sex2);
	strcpy(pos->sex, str_sex2);

	printf("请输入新的电话\n");
	scanf("%s",str_tel2);
	strcpy(pos->tel, str_tel2);

	printf("请输入新的地址\n");
	scanf("%s", str_adr2);
	strcpy(pos->adr, str_adr2);
	
}
int Size(PC* phead)
{
	int sz = 0;
	PC* cur = phead->next;
	assert(phead);
	while (cur != phead)
	{
		sz++;
		cur = cur->next;
	}
	return sz;
}

void Compare_ByName(PC*phead)
{
	int i =0;
	int j = 0;
	PC* cur = phead->next;
	PC* Next = cur->next;
	char Name_s[NAM_MAX] = "0";
	int age_s=0;
	char sex_s[SEX_MAX] = "0";
	char tel_s[TEL_MAX] = "0";
	char adr_s[ADR_MAX] = "0";
	assert(phead);

	for (i = 0; i < Size(phead)+1; i++)
	{
		for (j = 0; j < Size(phead) - i ;j++)
		{
			if ((strcmp(cur->name, Next->name) > 0) && (cur != phead) && (Next != phead))
			{
				strcpy(Name_s, cur->name);
				strcpy(cur->name, Next->name);
				strcpy(Next->name, Name_s);

				age_s = cur->age;
				cur->age = Next->age;
				Next->age = age_s;

				strcpy(sex_s, cur->sex);
				strcpy(cur->sex, Next->sex);
				strcpy(Next->sex, sex_s);

				strcpy(tel_s, cur->tel);
				strcpy(cur->tel, Next->tel);
				strcpy(Next->tel, tel_s);

				strcpy(adr_s, cur->adr);
				strcpy(cur->adr, Next->adr);
				strcpy(Next->adr, adr_s);
			}
			cur = cur->next;
			Next = Next->next;
		}
	}
}

void SaveData(PC* phead)
{
	FILE* fp = NULL;
	PC* cur = phead->next;
	assert(phead);
	fp = fopen("data.txt", "w");
	if (fp == NULL)
	{
		printf("%s", strerror(errno));
		return;
	}
	while (cur != phead)
	{
		fprintf(fp, "%s ", cur->name);
		fprintf(fp, "%d ", cur->age);
		fprintf(fp, "%s ", cur->sex);
		fprintf(fp, "%s ",  cur->tel);
		fprintf(fp, "%s ", cur->adr);
		fprintf(fp, "\n");//换行
		cur = cur->next;
	}
	fclose(fp);
	fp = NULL;
}

test.c是各个函数之间的调用:

test.c文件

#define _CRT_SECURE_NO_WARNINGS 1
#include"contact.h"
enum MyEnum
{
	Exit,
	Add,
	Dele,
	Find,
	Modify,
	Show,
	Destroy,
	Sort,
	Save
};

void Menu()
{
	//system("cls");
	printf("*******************************\n");
	printf("*********1.添加联系人*********\n");
	printf("*********2.删除联系人***********\n");
	printf("*********3.查找联系人************\n");
	printf("*********4.修改联系人*******\n");
	printf("*********5.显示所有联系人*******\n");
	printf("*********6.清空所有联系人*******\n");
	printf("*********7.按名字排序所有联系人*******\n");
	printf("*********8.将数据保存在文件中*******\n");
	printf("*********0.退出*******\n");
	printf("************************\n");
}
int main(void)
{

	PC* phead = BuyNewNode("000000", 0, "000000", "00000", "000000");//初始化一个头节点
	SaveFileData(phead);
	int input = 0;
	int sz = 0;//求联系人的个数
	char str_name[NAM_MAX] = "0";//用来通过姓名寻找
	do
	{
		Sleep(500);
		Menu();
		printf("请输入你的选择->");
		scanf("%d", &input);
		switch (input)
		{
		case Exit:
			printf("即将退出程序\n");
			for (int i = 0; i < 10; i++)
			{
				printf("-");
				Sleep(100);
			}
			break;

		case Add:
			if (phead == NULL)
			{
				phead= BuyNewNode("000000", 0, "000000", "00000", "000000");
			}
			ADDPc(phead);
			break;
		case Dele:
			printf("请输入你要删除的姓名:\n");
			scanf("%s", str_name);
			PC* pos = Find_by_name(phead, str_name);
			if (pos)
			{
				printf("姓名            年龄    性别    电话            地址\n");
				printf("%-15s\t%-5d\t%-5s\t%-15s\t%-10s\n", pos->name, pos->age, pos->sex, pos->tel, pos->adr);
				DelPc(pos);
				printf("删除成功\n");
			}
			else
			{
				printf("没有找到\n");
			}
			break;

		case Show:
			sz = Size(phead);
			printf("共有%d个联系人\n", sz);
			Print(phead);
			break;

		case Find:
			printf("请输入你要寻找的姓名:\n");
			scanf("%s", str_name);
			PC* pos1=Find_by_name(phead,str_name);
			if (pos1)
			{
				printf("姓名            年龄    性别    电话            地址\n");
				printf("%-15s\t%-5d\t%-5s\t%-15s\t%-10s\n", pos1->name, pos1->age, pos1->sex, pos1->tel, pos1->adr);
			}
			else
			{
				printf("没有找到\n");
			}
			break;

		case Modify:
			printf("请输入你要寻找的姓名:\n");
			scanf("%s", str_name);
			PC* pos2 = Find_by_name(phead, str_name);
			if (pos2)
			{
				printf("姓名            年龄    性别    电话            地址\n");
				printf("%-15s\t%-5d\t%-5s\t%-15s\t%-10s\n", pos2->name, pos2->age, pos2->sex, pos2->tel, pos2->adr);
				MoDify(pos2);
			}
			else
			{
				printf("没有找到\n");
			}
			break;

		case Destroy:
			DesTroy(phead);
			printf("销毁成功\n");
			break;

		case Sort:
			sz = Size(phead);
			printf("共有%d个联系人\n", sz);
			Compare_ByName(phead);
			Print(phead);
			break;

		case Save:
			SaveData(phead);
			printf("保存成功\n");
			break;

		default:
			printf("选择错误,请重新选择\n");
			break;
		}
	} while (input);
	return 0;
}

你可能感兴趣的:(C语言,数据结构,c语言,链表)