#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Logincheck
{
char account[1000];
int choose;
}Login;
typedef struct Student
{
char num[100];
char name[20];
int grade;
}Stu;
typedef struct ListNode
{
Stu student;
struct ListNode* next;
}ListNode;
//创建头节点
ListNode* createHead()
{
ListNode* Head = (ListNode*)malloc(sizeof(ListNode));
if (Head == NULL)
return NULL;
Head->next = NULL;
return Head;
}
//创建节点
ListNode* createNode(Stu student)
{
ListNode* pcur = (ListNode*)malloc(sizeof(ListNode));
if (pcur == NULL)
return NULL;
pcur->student = student;
pcur->next = NULL;
return pcur;
}
//数据判重
int is_repeat(char* num)
{
FILE* pf = fopen("学生数据.txt", "r");
while (1)
{
Stu judgedata = { 0 };
int judge = fscanf(pf, "%s%s%d", judgedata.num, judgedata.name, &judgedata.grade);
if (!strcmp(judgedata.num, num))
return 0;
if (judge == EOF)
return 1;
}
}
//插入节点
void insertNode(ListNode* head, Stu student)
{
ListNode* pcur = createNode(student);
pcur->next = head->next;
head->next = pcur;
}
//删除节点
void deleteNode(ListNode* head, char* num, FILE* pf)
{
ListNode* prev = head;
ListNode* pcur = head->next;
while (pcur && strcmp(pcur->student.num, num))
{
if (!strcmp(pcur->student.num, num))
{
prev->next = pcur->next;
free(pcur);
return;
}
prev = prev->next;
pcur = pcur->next;
}
if (!pcur)
{
printf("数据不存在,删除失败\n");
}
else
{
prev->next = pcur->next;
FILE* pfs = fopen("数据备份.txt", "a");//备份删除的数据,方便后续找回
fprintf(pfs, "%s\t%s\t%d\n", pcur->student.num, pcur->student.name, pcur->student.grade);
fclose(pfs);
free(pcur);
pf = fopen("学生数据.txt", "w+");//打开一个临时文件,将删除后的数据拷贝在临时文件中,然后删除原文件
pcur = head->next;
while (pcur)
{
fprintf(pf, "%s\t%s\t%d\n", pcur->student.num, pcur->student.name, pcur->student.grade);
pcur = pcur->next;
}
fclose(pf);
printf("删除成功!\n");
}
}
//打印链表
void printList(ListNode* head)
{
ListNode* pcur = head->next;
printf("编号\t姓名\t成绩\n");
while (pcur)
{
printf("%s\t%s\t%d\n", pcur->student.num, pcur->student.name, pcur->student.grade);
pcur = pcur->next;
}
}
//查找节点
void seekNode(ListNode* head, char* num)
{
ListNode* pcur = head->next;
while (pcur && strcmp(pcur->student.num, num))
{
pcur = pcur->next;
}
if (pcur == NULL)
printf("数据不存在\n");
else
{
printf("编号姓名成绩\n");
printf("%s\t%s\t%d\n", pcur->student.num, pcur->student.name, pcur->student.grade);
}
}
//修改节点
void modifyNode(ListNode* head, char* num, Stu student)
{
ListNode* pcur = head->next;
while (pcur && strcmp(pcur->student.num, num))
{
pcur = pcur->next;
}
if (pcur == NULL)
printf("要修改的数据不存在\n");
else if (!is_repeat(pcur->student.num))
printf("该编号已存在,请检查后重新修改!\n");
else
{
pcur->student = student;
FILE* pf = fopen("学生数据.txt", "w+");//将修改后的数据拷贝到文件中
pcur = head->next;
while (pcur)
{
fprintf(pf, "%s\t%s\t%d\n", pcur->student.num, pcur->student.name, pcur->student.grade);
pcur = pcur->next;
}
printf("修改成功\n");
fclose(pf);
}
}
//登录界面
Login logInterface()
{
Login log;
printf("******************\n");
printf("请输入账户密码\n");
scanf("%s", log.account);
printf("请选择登录或注册(0.登录 1.注册)\n");
scanf("%d", &log.choose);
printf("******************\n");
return log;
}
//登录检测
char* loginCheck(Login log)
{
FILE* pf = NULL;
if (log.choose)//判断用户是要注册还是登录
{
pf = fopen("账户数据.txt", "a");
fprintf(pf, "%s\n", log.account);
printf("注册成功\n");
fclose(pf);
return "access";//注册成功,返回一个token
}
else if (log.choose == 0)
{
pf = fopen("账户数据.txt", "r");
if (pf == NULL)
printf("用户不存在!\n");
else
{
while (1)//比对数据,成功返回一个token
{
char strcheck[1000] = { 0 };
int judge = fscanf(pf, "%s", strcheck);
if (!strcmp(strcheck, log.account))
return "access";
if (judge == EOF)
break;
}
fclose(pf);
}
}
return "fail";
}
//菜单
void menu()
{
printf("******************\n");
printf("0.退出程序\n");
printf("1.浏览数据\n");
printf("2.录入数据\n");
printf("3.删除数据\n");
printf("4.修改数据\n");
printf("5.查找数据\n");
printf("6.恢复备份\n");
printf("7.按成绩排序\n");
printf("******************\n");
}
//文件操作
//数据初始化
void initData(FILE* pf, ListNode* head)
{
pf = fopen("学生数据.txt", "r");
if (pf == NULL)
printf("数据读取失败,请重试\n");
else
{
ListNode* pcur = head->next;
Stu student;
while (fscanf(pf, "%s%s%d", student.num, student.name, &student.grade) != EOF)
{
insertNode(head, student);
}
fclose(pf);
}
}
//数据保存
int saveData(FILE* pf, Stu student)
{
pf = fopen("学生数据.txt", "a");
if (pf == NULL)
printf("数据录入失败\n");
else if (!is_repeat(student.num))
printf("该编号已存在,请检查后重新录入!\n");
else
{
fprintf(pf, "%s\t%s\t%d\n", student.num, student.name, student.grade);//将录入的数据保存在文件中
printf("已成功录入\n");
return 1;
fclose(pf);
}
return 0;
}
//恢复备份
void restoreBackup(FILE* pf, char* num)
{
pf = fopen("学生数据.txt", "a");
FILE* pfs = fopen("数据备份.txt", "r");
if (pfs == NULL)
printf("该目录下没有数据备份,无法恢复\n");
else
{
Stu student;
int flag = 1;
while (fscanf(pfs, "%s%s%d", student.num, student.name, &student.grade) != EOF)
{
if (!strcmp(num, student.num))
{
fprintf(pf, "%s\t%s\t%d\n", student.num, student.name, student.grade);
flag = 0;
}
}
if (flag)
printf("要恢复的数据不存在\n");
else printf("已成功恢复备份!\n");
fclose(pf);
fclose(pfs);
}
}
//对数据进行排序
void sortData(ListNode* head)
{
for (ListNode* first = head->next; first != NULL; first = first->next)
{
for (ListNode* second = head->next; second != NULL; second = second->next)
{
if (second->next != NULL)
{
if (second->student.grade < second->next->student.grade)
{
Stu student = second->student;
second->student = second->next->student;
second->next->student = student;
}
}
}
}
}
//获取用户操作
void keyDown(ListNode* head, FILE* pf)
{
int input = 0;
printf("请用户选择操作方式\n");
scanf("%d", &input);
Stu student;
switch (input)
{
case 0:
printf("程序正在退出\n");
system("pause");
exit(0);
break;
case 1:
if (head->next == NULL)
printf("暂时没有数据,无法浏览\n");
else printList(head);
break;
case 2:
printf("请用户输入学生信息:\n");
scanf("%s %s %d", student.num, student.name, &student.grade);
if (saveData(pf, student))
insertNode(head, student);
break;
case 3:
printf("请用户输入要删除的学生编号:");
scanf("%s", student.num);
deleteNode(head, student.num, pf);
break;
case 4:
printf("请用户输入要修改的学生的编号:");
char str[1000];
scanf("%s", str);
printf("请用户输入新的学生信息:\n");
scanf("%s %s %d", student.num, student.name, &student.grade);
modifyNode(head, str, student);
break;
case 5:
printf("请用户输入要查找的学生编号:");
scanf("%s", student.num);
seekNode(head, student.num);
break;
case 6:
printf("请输入要恢复的学生编号\n");
char back[1000] = { 0 };
scanf("%s", back);
if (!is_repeat(back))
printf("编号重复,请检查后重新输入\n");
else
{
restoreBackup(pf, back);
initData(pf, head);
if (!remove("数据备份.txt"))
printf("备份已删除\n");
}
break;
case 7:
sortData(head);
printList(head);
break;
default:
printf("非法操作,请重新输入!!!\n");
break;
}
}
int main()
{
FILE* pf = NULL;
while (1)
{
Login log = logInterface();
char* check= loginCheck(log);
if (!strcmp(check, "access"))//通过token判断是否存在这么一个用户
{
printf("登陆成功\n");
break;
}
else printf("登录失败!请重试\n");
system("pause");
system("cls");
}
system("pause");
system("cls");
ListNode* pHead = createHead();
initData(pf, pHead);
while (1)
{
menu();
keyDown(pHead, pf);
system("pause");
system("cls");
}
return 0;
}