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

双向循环链表实现—通讯录(学生管理系统,自行车管理系统,影院管理系统)—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语言课设(万能模板)—数据结构—用文件存储数据
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 20typedef 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;}

推币机的世界