小和尚的内心OS:最近比较忙,只能在周末更博了【暴风哭泣】
这次给大家介绍的是使用链表对文件内容进行增删改查~~~
注:以题目管理系统为例
----------------------------------------------------------------------------------------------------------------------------
整体思路:定义结构体,通过链表以结构体为单位向文件中读写数据
一.定义结构体
链表的相关操作是通过结构体指针来完成的,所以必须在结构体内部定义指针
然而,我们是以结构体为单位对文件进行读写,如果直接把指针定义在struct Course内部
那么我们的文件里面就会有与指针有关的内容,也就是地址
实际上我们只用把题目要求的信息存进文件即可,比如题目,学生等等,不需要存指针地址
因此,我们要定义两个结构体:
struct Course {
char title[30]; //题目
char tName[10];//教师名字
char sName[10]; //学生名字
char need[400]; //题目要求
};
struct Node {
struct Course data;//需要储存的信息
struct Node* pNext;//结构体指针
};
通过struct Node{}可以实现只将struct Course{}里面的信息存进文件,而不会存入地址
二.定义函数,实现节点的创建
我们都知道,使用链表是由一个个节点连接而成,所以在使用链表之前我们要先创建节点
//创建节点
struct Node* createNode(struct Course* pData) {
struct Node* pNew = (struct Node*) malloc(sizeof(struct Node));
if(NULL == pNew) {
return NULL;
}
pNew -> pNext = NULL;
strcpy(pNew -> data.title, pData -> title);
strcpy(pNew -> data.tName, pData -> tName);
strcpy(pNew -> data.sName, pData -> sName);
strcpy(pNew -> data.need, pData -> need);
return pNew;
}
三.定义函数,将节点连接起来
连接节点,实际上就是把新创建的节点连接到前一个指针的末尾
//添加一个节点到指针末尾
void addendNode(struct Node** root, struct Course* pData) {
if(root == NULL) return;
if(*root == NULL) { //传进来一个空列表
*root = createNode(pData);
return;
}
struct Node* pTemp = *root;
//让pTemp指向链表的最后一个节点
while(pTemp -> pNext) {
pTemp = pTemp -> pNext;
}
pTemp -> pNext = createNode(pData);//把新节点添加到pTemp后面
}
有了这些操作,我们就可以很顺利地进行链表的增删改查啦!
一.添加信息
//添加学生信息-题目
//-------------------------------------------------
void addCourse() {
//1 打开文件
FILE* fp = fopen("list2.txt", "rb");
if(NULL == fp) {
printf("数据获取失败!即将退出系统...");
Sleep(3000);
exit(0);
}
//2 读取问文件内容并存到容器中
struct Node* pList = NULL;
int r;
struct Course temp;
while(1) {
r = fread(&temp, 1, sizeof(struct Course), fp); //temp表示存放输入数据的首地址
if(r <= 0) { //没读到
break;
} else {
//读到学生信息
//创建一个链表节点并添加到链表中
addendNode(&pList, &temp);
}
}
//3 关闭文件
fclose(fp);
printf("请输入要添加的题目名字:");
scanf("%s", temp.title);
printf("请输入要添加的要求:");
scanf("%s", temp.need);
printf("请输入要添加的老师名字:");
scanf("%s", temp.tName);
printf("请输入要添加的学生名字:");
scanf("%s", temp.sName);
addendNode(&pList, &temp);
fp = fopen("list2.txt", "wb");
struct Node* pTemp = pList;
//写入数据
while(pTemp) {
fwrite(&(pTemp -> data), 1, sizeof(struct Course), fp);
pTemp = pTemp -> pNext;
}
fclose(fp);
printf("信息添加成功!\n");
struct Node* pDel = pList;
while(pList -> pNext) {
pList = pDel -> pNext;
free(pDel);//释放内存
pDel = NULL;
pDel = pList;
}
free(pList);
pList = NULL;
}
二.删除信息
//删除信息
//-----------------------------------------------------------------------------
void deleteCourse() {
FILE* fp = fopen("list2.txt", "rb");
if(NULL == fp) {
printf("数据获取失败!即将退出系统...");
Sleep(3000);
exit(0);
}
struct Node* pList = NULL;
int r;
struct Course temp;
while(1) {
r = fread(&temp, 1, sizeof(struct Course), fp); //temp表示存放输入数据的首地址
if(r <= 0) { //没读到
break;
} else {
//读到学生信息
//创建链一个表节点并添加到链表中
addendNode(&pList, &temp);
}
}
fclose(fp);
char input[40];
struct Node* pDel, *pDelPret;
int flag = 0;
pDel = pDelPret = pList;
printf("请输入要删除的题目\n");
scanf("%s", input);
while(pDel) {
if(strcmp(pList -> data.title, input) == 0) {
pList = pList -> pNext;
flag = 1;
break;
}
if(strcmp(pDel -> data.title, input) == 0) {
if(pDel -> pNext != NULL) {
pDelPret -> pNext = pDel -> pNext;
} else {
pDelPret -> pNext = NULL;
}
flag = 1;
break;
}
pDelPret = pDel;
pDel = pDel -> pNext;
}
if(flag) {
printf("\n删除成功!\n");
} else {
printf("该题目不存在!");
}
flag = 0;
//1 打开文件
fp = fopen("list2.txt", "wb");
struct Node* pTemp = pList;
//写入数据
while(pTemp) {
fwrite(&(pTemp -> data), 1, sizeof(struct Course), fp);
pTemp = pTemp -> pNext;
}
fclose(fp);
pDel = pList;
while(pList -> pNext) {
pList = pDel -> pNext;
free(pDel);//释放内存
pDel = NULL;
pDel = pList;
}
free(pList);
pList = NULL;
}
三.修改信息
//修改信息
//--------------------------------------------------------------------------------------
void reviseInformation() {
char input[40];
char inputRevise[40];
FILE* fp = fopen("list2.txt", "rb");
if(NULL == fp) {
printf("数据获取失败!即将退出系统...");
Sleep(3000);
exit(0);
}
struct Node* pList = NULL;
int r;
struct Course temp;
while(1) {
r = fread(&temp, 1, sizeof(struct Course), fp); //temp表示存放输入数据的首地址
if(r <= 0) { //没读到
break;
} else {
//读到学生信息
//创建链一个表节点并添加到链表中
addendNode(&pList, &temp);
}
}
struct Node* pRevise;
pRevise = pList;
int flag = 0;
fclose(fp);
printf("请输入要修改的题目\n");
scanf("%s", input);
printf("请输入修改后的题目\n");
scanf("%s", inputRevise);
while(pRevise) {
if(strcmp(pRevise -> data.title, input) == 0) {
strcpy(pRevise -> data.title, inputRevise);
printf("\n修改成功!\n");
flag = 1;
break;
}
pRevise = pRevise -> pNext;
}
if(flag != 1) {
printf("未找到相关题目!");
}
//1 打开文件
fp = fopen("list2.txt", "wb");
struct Node* pTemp = pList;
//写入数据
while(pTemp) {
fwrite(&(pTemp -> data), 1, sizeof(struct Course), fp);
pTemp = pTemp -> pNext;
}
fclose(fp);
//删除链表
struct Node* pDel = pList;
while(pList -> pNext) {
pList = pDel -> pNext;
free(pDel);//释放内存
pDel = NULL;
pDel = pList;
}
free(pList);
pList = NULL;
}
注意:1.其实我们在修改信息之前要先找到对应的题目,之后再进行修改,我这里没写,小伙伴们 可以自行补上
2.我们也可以修改相关题目的其他信息,只用将与“题目”相关的代码换成其他信息即可
可以将data.title换成data.studentName等等,也就是结构体里面的变量
四.遍历信息
我们这里首先要写一个函数遍历结构体
void travel(struct Node* root) {
if(NULL == root) return;
while(root) {
printf("%s\t%s\t%s\t%s\n", root -> data.title, root -> data.tName, root -> data.sName, root -> data.need);
root = root -> pNext;
}
printf("-------------------------------------------\n");
}
接着写一个函数遍历文件内容:
void lookthroughAll() {
FILE* fp = fopen("list2.txt", "rb");
if(NULL == fp) {
printf("数据获取失败!即将退出系统...");
Sleep(3000);
exit(0);
}
struct Node* pList = NULL;
int r;
struct Course temp;
while(1) {
r = fread(&temp, 1, sizeof(struct Course), fp); //temp表示存放输入数据的首地址
if(r <= 0) { //没读到
break;
} else {
//读到学生信息
//创建链一个表节点并添加到链表中
addendNode(&pList, &temp);
}
}
fclose(fp);
//4 遍历容器输出
travel(pList);
//5 删除整个列表
struct Node* pDel = pList;
while(pList -> pNext) {
pList = pDel -> pNext;
free(pDel);//释放内存
pDel = NULL;
pDel = pList;
}
free(pList);
pList = NULL;
}
---------------------------------------------------------------------------------------------------------------------------------
好嘚,到这里我们系统的所有功能都已经写好了,就差图形化界面的设计了
下一篇我们会举使用EGE的例子~~~