数据结构中最简单的也就是顺序表以及链表,在链表中可以完成管理系统之类的,只要掌握这个学生管理系统,其他的管理系统都可以做,只要稍加改动,就可以改编成其它系统的,这里我先写出一个学生管理系统,后面,我会写一个疫苗管理系统,大家可以对比着看。
这里采用多文件编码方式进行编写且具有文件操作
这部分是StudentSystem.c文件中的
#include "singleList.h"
struct Node* list = NULL;
void systemMenu()
{
//这里是菜单栏
printf("-------【学生管理系统】-------\n");
printf("\t\t0.退出系统\n");
printf("\t\t1.插入信息\n");
printf("\t\t2.浏览信息\n");
printf("\t\t3.删除信息\n");
printf("\t\t4.修改信息\n");
printf("\t\t5.查找信息\n");
//printf("\t\t6.保存信息\n");//这里不用专门做,因为系统会自动保存到文件之中
printf("-----------------------------\n");
printf("请输入0--5:");
//每次交互,若没告诉别人这个地方需要交互,则会有瑕疵
}
void keyDown()//按键交互
{
int userkey;
struct student tempData;//存储临时的data
scanf("%d",&userkey);
switch(userkey)
{
case 0:
printf("\t\t【退出系统】\n");
system("pause");//使屏幕悬停
exit(0);
break;
case 1:
printf("\t\t【插入信息】\n");
printf("请输入姓名,学号,年龄,电话,住址:");
scanf("%s%s%d%s%s",tempData.name,tempData.num,&tempData.age,tempData.tel,tempData.addr);
//整型要进行取地址
insertNodeByHead(list,tempData);
break;
case 2:
printf("\t\t【浏览信息】\n");
printList(list);
break;
case 3:
printf("\t\t【删除信息】\n");
printf("请输入要删除学生的姓名:");
scanf("%s",tempData.name);
deleteNodeByAppoinName(list,tempData.name);
saveInfoToFile("student.txt",list);
break;
case 4:
printf("\t\t【修改信息】\n");
printf("请输入要修改学生的学号:");
scnaf("%s",tempData.num);
if(searchNodeByAppoinNum(list,tempData.num) == NULL)
{
printf("未找到相关信息,修改失败!!\n");
}
else
{
struct Node* curNode = searchNodeByAppoinNum(list,tempData.num);
printf("请输入该生新名字,学号,年龄,电话,住址:");
scanf("%s%s%d%s%s",curNode->data.name,curNode->data.num,curNode->data.age,curNode->data.tel,curNode->data.addr);//为什么能这样改,因为这里返回的是一个指针,可以直接作用到它的数据域
saveInfoToFile("student.txt",list);//保存到哪里,是哪个链表
}
break;
case 5:
printf("\t\t【查找信息】\n");
printf("请输入要查找的学生的学号:");
scanf("%s",tempData.num);
if(searchNodeByAppoinNum(list,tempData.num) == NULL)//进行判断,看是否查找到了信息
{
printf("未找到相关信息,查找失败!!\n");
}
else
{
printNode(searchNodeByAppoinNum(list,tempData.num));
}
break;
default:
printf("输入错误!请重新输入:\n");
break;
}
}
int main()
{
list = createList();
while(1)
{
systemMenu();
keyDown();
system("pause");
system("cls");
}
system("pause");
return 0;
}
这里是singleList.h文件中的
//也就是单链表
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct student
{
char name[20];//名字
char num[10];//学号
int age;//年龄
char tel[20];//电话号码
char addr[20];//家庭地址
};
//写数据结构,死方法:
//1、抽象单一个体
//2、描述最初状态:初始化-->初始化变量
//3、插入、删除
//4、打印遍历
struct Node
{
struct student data;
struct Node* next;
};
//1、链表使什么东西:就是结构体变量和结构体变量连接在一起
//2、指针第二种变为变量的方式:动态内存分配
//3、用第一个结点表示整个链表
struct Node* createList()
{
//链表中的两种类型:
//有表头链表:第一个结点不存储数据
//无表头链表:第一个结点存储数据
//1、产生一个结构体变量
struct Node* listHeadNode = (struct Node*)malloc(sizeof(struct Node));
//2、初始化链表
listHeadNode->next = NULL;
return listHeadNode;
}
struct Node* createNode(struct student data)//链表的表头和结点是一样的,没有什么区别
{
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = data;
newNode->next = NULL;
return newNode;
}
//插入哪个链表,插入的数据是多少:功能就是录入信息
void insertNodeByHead(struct Node* listHeadNode,struct student data)
{
//创建插入的结点:
struct Node* newNode = createNode(data);
//要是想不清楚就画图
newNode->next = listHeadNode->next;//连的是newNode跟listHeadNode之间的线
listHeadNode->next = newNode;//连的是listheadNode跟newNode之间的线,而newNode是新插入的结点
}
//删除 根据姓名 进行删除
void deleteNodeByAppoinName(struct Node* listHeadNode,char* name)
{
struct Node* posFrontNode = listHeadNode;
struct Node* posNode = listHeadNode->next;
//在删除之前,首先要判断链表是否为空
if(posNode == NULL)
{
printf("无相关内容,无法删除!!");
return ;
}
else
{
while(strcmp(posNode->data.name,name))
{
posFrontNode = posNode;
posNode = posFrontNode->next;
//不可能一直找下去,要有个停的地方
if(posNode == NULL)
{
printf("无相关内容,无法删除!!");
return ;
}
}
//找到了
posFrontNode->next = posNode->next;
free(posNode);
}
}
//查找 根据学号 进行查找
struct Node* searchNodeByAppoinNum(struct Node* listHeadNode,char* num)
{
struct Node* pMove = listHeadNode->next;//这里是移动的指针
if(pMove == NULL)
{
return pMove;
}
else
{
while(strcmp(pMove->data.num,num))
{
pMove = pMove->next;//这里学号如果不同,就得一直往下走
if(pMove == NULL)//防止其发生中断错误,所以要进行防御性编程
{
break;
}
}
return pMove;//返回所找到的结点
}
}
//打印:插入时的当前结点
void printNode(struct Node* curNode)
{
printf("姓名\t学号\t年龄\t电话\t\t住址\n");
printf("%s\t%s\t%d\t%s\t%s\n",curNode->data.name,curNode->data.num,curNode->data.age,curNode->data.tel,curNode->data.addr);
}
//打印:就是系统的浏览信息
void printList(struct Node* listHeadNode)//表头打印
{
struct Node* pMove = listHeadNode->next;
printf("姓名\t学号\t年龄\t电话\t\t住址\n");
while(pMove)
{
printf("%s\t%s\t%d\t%s\t%s\n",pMove->data.name,pMove->data.num,pMove->data.age,pMove->data.tel,pMove->data.addr);
pMove->next;
}
printf("\n");
}
//文件操作
//读的是哪个文件,保存到哪个信息中去
void readInfoFromFile(char* fileName,struct Node* listHeadNode)
{
//定义文件指针
//打开文件
FILE* fp = fopen(fileName,"r");//文件以读的形式进行打开
//如果文件不存在
if(fp == NULL)
{
fp = fopen(fileName,"w");//这里文件就以写的形式进行打开,
//如果文件不存在,这里系统就会自动生成一个文件
}
//用格式化读取
struct student tempData;
while(fscanf(fp,"%s\t%s\t%d\t%s\t%s\n",tempData.name,tempData.num,&tempData.age,tempData.tel,tempData.addr)!=EOF)//按照这个格式进行读取文件,从哪里读,从文件指针哪里读,所以最前面是fp
//加\t是以表格的形式进行写,以表格的形式进行读
{
insertNodeByHead(listHeadNode,tempData);
memset(&tempData,0,sizeof(tempData));//开始进行初始化一下
}
fclose(fp);
}
//存储文件信息
//存储到哪个文件去,把哪一个链表中的信息存储到这里来
void saveInfoToFile(char* fileName,struct Node* listHeadNode)
{
FILE* fp = fopen(fileName,"w");
//用格式化打印到文件中去
struct Node* pMove = listHeadNode->next;
while(pMove)
{
fprintf(fp,"%s\t%s\t%d\t%s\t%s\n",pMove->data.name,pMove->data.num,pMove->data.age,pMove->data.tel,pMove->data.addr);
pMove = pMove->next;
}
fclose(fp);
//修改需要保存文件
//查找不需要保存文件
}
这就是完整的链表学生管理系统,希望对大家有用。好好看,好好研究这个链表的格式,对以后写个啥是非常有帮助的!!!