#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; }