头文件代码
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct Student
{
char name[20];
char number[15];
int age;
char Telephone[15];
char address[20];
}; //定义结构体类型
struct Node {
struct Student data; //以结构体数组类型数据为数据域,例如int data
struct Node* next; //指针域
};
struct Node* createList()
{
struct Node* listHeadNode = (struct Node*)malloc(sizeof(struct Node));
listHeadNode->next = NULL; //创建空的头节点
return listHeadNode;
}
struct Node* createNode(struct Student data)
{
struct Node* newnode = (struct Node*)malloc(sizeof(struct Node));
newnode->data = data; //把传进来的学生data插进新生成的节点
newnode->next = NULL;
return newnode;
}
void InsertNode(struct Node* listHeadNode, struct Student data) {
struct Node* newnode = createNode(data); //把新生成的节点赋值给newnode
newnode->next = listHeadNode->next; //利用头插法插入新节点
listHeadNode->next = newnode;
}
void printlist(struct Node* listHeadNode)//遍历链表打印
{
struct Node* temp = listHeadNode->next;
printf("姓名\t学号\t\t年龄\t电话\t\t住址\n");
while (temp != NULL)
{
printf("%s\t%s\t%d\t%s\t%s\n", temp->data.name, temp->data.number, temp->data.age, temp->data.Telephone, temp->data.address);
temp = temp->next;
}
printf("\n");
}
struct Node* SearchNode(struct Node* listHeadNode, char* num)//查找特定学生学号节点,char *num是传入的字符串类型数组
{
struct Node* temp = listHeadNode->next; //listHeadNode->next才是有数据的第一个节点
if (temp == NULL)
{
return temp;
}
while (temp != NULL)
{
if (strcmp(temp->data.number, num) == 0) //strcmp函数比较,两个字符串相等返回0,temp->data.number>num返回1否则返回-1
break;
temp = temp->next;
}
return temp;
}
void printNode(struct Node* temp)//打印特定节点数据
{
printf("姓名\t学号\t\t年龄\t电话\t\t住址\n");
printf("%s\t%s\t%d\t%s\t%s\n", temp->data.name, temp->data.number, temp->data.age, temp->data.Telephone, temp->data.address);
}
void ReadToFile(const char* filename, struct Node* listHeadNode)//读取文件数据至链表
{
FILE* fp = fopen(filename, "r");//文件只读取方式
if (fp == NULL)
{
fp = fopen(filename, "w"); //文件只写方式,如果文件中没有数据就以只写的方式创建,不可在二次调试程序的时候再以只写方式进行写入文件数据,不然会直接清空原有数据
}
struct Student data;
while (fscanf(fp, "%s\t%s\t%d\t%s\t%s\t", data.name, data.number, &data.age, data.Telephone, data.address) != EOF)
{ //fscanf函数以对应的格式写入数据到目的数据体中写入一次数据体就换行一次,即原先SaveToFile函数以%s\t%s\t%d\t%s\t%s\n写入
InsertNode(listHeadNode, data);
memset(&data, 0, sizeof(data)); //初始化data再进行下次赋值写入到insertNode自定义函数中去
}
fclose(fp);
}
void SaveToFile(const char* filename, struct Node* listHeadNode) {
FILE* fp = fopen(filename, "w");
struct Node* temp = listHeadNode->next;
while (temp != NULL)
{
fprintf(fp, "%s\t%s\t%d\t%s\t%s\n", temp->data.name, temp->data.number, temp->data.age, temp->data.Telephone, temp->data.address); //注意没写完一次数据体就\n换行
temp = temp->next;
}
fclose(fp);
}
void DeleteAtNumber(struct Node* listHeadNode, char* number)
{
struct Node* FontNode = listHeadNode; //此方法是以防只有一个数据节点的删除
struct Node* Node = listHeadNode->next;
if (Node == NULL)
{
printf("无相关内容,无法删除\n");
return;
}
while (strcmp(Node->data.number, number)==0)
{
FontNode = Node;
Node = Node->next;
if (Node == NULL)
{
printf("无相关内容,无法删除\n");
return;
}
}
FontNode->next = Node->next; //Node是需要删除的节点,先把Node前一个节点next链接到Node节点next再删除,即使是尾节点Node->next=NULL,刚好FontNode->next=NULL;
free(Node);
SaveToFile("Student.txt", listHeadNode);
}
具体调用函数实现代码
#include "Student2.h"
struct Node* list=NULL;
void SystemMenu()
{
printf("\t\t\t\t**********欢迎使用学生信息管理系统**********\n");
printf("\t\t\t\t____________________________________________\n");
printf("\t\t\t\t请选择您所需的服务选项\n");
printf("\t\t\t\t(1).【退出系统】\n");
printf("\t\t\t\t(2).【插入信息】\n");
printf("\t\t\t\t(3).【浏览信息】\n");
printf("\t\t\t\t(4).【删除信息】\n");
printf("\t\t\t\t(5).【修改信息】\n");
printf("\t\t\t\t(6).【查找信息】\n");
}
void KeyDown()
{
int userKey;
struct Student data;
scanf("%d", &userKey);
switch (userKey)
{
case 1:
printf("\t\t\t\t(1).【退出系统】\n");
system("pause");
exit(0);
break;
case 2:
printf("\t\t\t\t(2).【插入信息】\n");
printf("请输入姓名,学号,年龄,电话,住址\n");
scanf("%s%s%d%s%s",data.name,data.number,&data.age,data.Telephone,data.address);
InsertNode(list,data);
SaveToFile("Student.txt", list);
break;
case 3:
printf("\t\t\t\t(3).【浏览信息】\n");
printlist(list);
break;
case 4:
printf("\t\t\t\t(4).【删除信息】\n");
printf("请输入需要删除的学生学号");
scanf("%s",data.number);
DeleteAtNumber(list,data.number);
break;
case 5:
printf("\t\t\t\t(5).【修改信息】\n");
printf("请输入需要修改学生的学号\n");
scanf("%s", data.number);
if (SearchNode(list, data.number) == NULL) {
printf("未找到相关信息");
}
else
{
struct Node* temp = SearchNode(list, data.number);
printf("请输入新的姓名,学号,年龄,电话,住址\n");
scanf("%s%s%d%s%s", temp->data.name, temp->data.number, &temp->data.age, temp->data.Telephone, temp->data.address);
SaveToFile("Student.txt",list);
}
break;
case 6:
printf("\t\t\t\t(6).【查找信息】\n");
printf("请输入查找学号\n");
scanf("%s", data.number);
if (SearchNode(list, data.number)==NULL) {
printf("未找到相关信息");
}
else
printNode(SearchNode(list, data.number));
break;
default:
printf("输入错误!请重新输入\n");
break;
}
}
int main()
{
list = createList();
ReadToFile("Student.txt", list);
while (1)
{
SystemMenu();
KeyDown();
system("pause");
system("cls");
}
}