C语言链表项目-学生信息管理系统

    技术2022-07-11  122

    核心知识

    单向链表基本操作+对文件的基本操作

    使用说明

    请先建好一个.txt文件并记下路径名,文件可以为空,也可以预先存好数据建议创建一个空文件,通过程序来向文件中存数据。手动去文件中存数据需要严格按照格式。

    如果想预先手动存一些数据,需要按照以下格式:

    在某些编译器上,姓名可能不支持中文


    姓名1 语文 数学 英语 计算机 C语言 平均分 总分1

    姓名n 语文 数学 英语 计算机 C语言 平均分 总分n


    文件结尾,也就是最后一行的总分n后面不要有任何字符。

    代码附上

    #include <stdio.h> #include <string.h> #include <stdlib.h> #include <malloc.h> #define MAXNAME 30 #define MAXSUBJECT 5 #define SPACE ' ' typedef struct student { char name[MAXNAME]; int score[MAXSUBJECT]; double aver; int sum; } STUDENT; typedef struct node { STUDENT data; struct node *next; } NODE, *LIST; int i, choice; char ch, c, c2; char s1[10] = "name"; char s2[10] = "average"; char s3[10] = "sum"; char s4[10] = "chinese"; char s5[10] = "math"; char s6[10] = "english"; char s7[10] = "computer"; char s8[10] = "c"; char FileName[100]; LIST headp = NULL; // 读入文件时,添加链表成员 void AddFscanf(NODE); // 使用说明 void Instructions(); // 进行完一次操作后,询问是否继续 void Ask(); // 打印分割线 void SplitLine(); // 操作1,用户输入时,添加链表成员, void AddUserInput(); // 操作2,删除节点 void Delete(); // 操作3,查询某个节点信息 void Inquire(); // 操作4,更新某个节点信息 void Update(); // 操作5,排序学生信息 void Sort(); // 操作6,保存信息到文件中 void Save(); // 操作7,打印链表 void Print(); // 释放链表 void Free(); int main(void) { FILE *fp = NULL; NODE head; NODE temp; headp = &head; head.next = NULL; temp.next = NULL; printf("请输入文件的绝对路径+文件名(仅限 .txt 文件)\n\n"); printf("例如,若您要打开D盘根目录下的 info.txt 文件\n"); printf("则应输入\"D:/info.txt\"(您输入的字符均应为英文字符)\n"); scanf("%s", FileName); getchar(); if ((fp = fopen(FileName, "r")) == NULL) { printf("\n\"%s\" 打开失败\n\n", FileName); exit(EXIT_FAILURE); } printf("\n\"%s\" 打开成功!\n", FileName); printf("\n正在鉴定文件是否为空...\n"); c2 = getc(fp); fclose(fp); if (c2 == EOF) printf("打开的文件为空文件,仅可进行写入操作!\n"); else { printf("文件非空,可进行任意操作\n\n"); printf("正在重新打开该文件...\n"); if ((fp = fopen(FileName, "r")) == NULL) { printf("can't open \"%s\" \n", FileName); exit(EXIT_FAILURE); } printf("正在读取该文件中的数据...\n"); while (1) { fscanf(fp, "%s", temp.data.name); for (i = 0; i < MAXSUBJECT; i++) fscanf(fp, "%d", &temp.data.score[i]); fscanf(fp, "%lf", &temp.data.aver); fscanf(fp, "%d", &temp.data.sum); ch = getc(fp); AddFscanf(temp); if (ch == EOF) break; } printf("文件数据读取成功!\n"); fclose(fp); } while (1) { Instructions(); switch (choice) { case 1: AddUserInput(); break; case 2: Delete(); break; case 3: Inquire(); break; case 4: Update(); break; case 5: Sort(); break; case 6: Save(); break; case 7: Print(); break; case 0: printf("Bye~ Have a good day! \n\n"); exit(EXIT_FAILURE); default: break; } Ask(); } Free(); return 0; } void Free() { LIST temp = headp->next; LIST deletep = NULL; while (temp != NULL) { deletep = temp; temp = temp->next; free(deletep); } } void Save() { FILE *fp = NULL; int flag = 0; LIST temp = headp->next; if ((fp = fopen(FileName, "w")) == NULL) { printf("can't open \" %s \" \n", FileName); exit(EXIT_FAILURE); } while (temp != NULL) { if (flag) fprintf(fp, "\n"); fprintf(fp, "%s ", temp->data.name); for (i = 0; i < MAXSUBJECT; i++) fprintf(fp, "%d ", temp->data.score[0]); fprintf(fp, "%.2f ", temp->data.aver); fprintf(fp, "%d", temp->data.sum); flag = 1; temp = temp->next; } printf("\n保存成功!"); fclose(fp); } void Sort() { LIST temp = NULL; STUDENT t; int lenth = 0, j; if (headp->next == NULL) { printf("数据为空!仅可进行写入操作!\n"); return; } temp = headp->next; while (temp != NULL) { lenth++; temp = temp->next; } for (i = lenth - 1; i > 0; i--) { temp = headp->next; for (j = 0; j < i; j++) { if (temp->data.sum < temp->next->data.sum) { t = temp->data; temp->data = temp->next->data; temp->next->data = t; } else if (temp->data.sum == temp->next->data.sum) { if (strcmp(temp->data.name, temp->next->data.name) > 0) { t = temp->data; temp->data = temp->next->data; temp->next->data = t; } } temp = temp->next; } } printf("\n排序成功!"); } void Update() { LIST temp = NULL; int flag; char NAME[MAXNAME]; if (headp->next == NULL) { printf("数据为空!\n"); return; } temp = headp; printf("请输入要更新的学生姓名:\n"); while (1) { temp = headp; fflush(stdin); scanf("%s", NAME); getchar(); while (temp != NULL) { if (strcmp(temp->data.name, NAME) == 0) break; temp = temp->next; } if (temp == NULL) { printf("错误!库中没有该学生的信息\n"); printf("键入'n'退出该功能,或键入'y'重新输入\n"); while (1) { flag = 0; scanf("%c", &c); getchar(); if (c == 'y' || c == 'Y') { printf("请重新输入要更新学生的姓名\n"); break; } else if (c == 'n' || c == 'N') { flag = 1; break; } else printf("输入非法!请输入'y'或'n',不要输入其它字符\n"); } if (flag) break; } else { temp->data.sum = 0; temp->data.aver = 0.0; printf("请依次输入该学生语文、数学、英语、计算机、C语言,五门课的成绩\n"); for (i = 0; i < MAXSUBJECT; i++) { scanf("%d", &temp->data.score[i]); temp->data.sum += temp->data.score[i]; } temp->data.aver = temp->data.sum * 1.0 / MAXSUBJECT; printf("\n更新成功!"); break; } } } void Inquire() { LIST temp = NULL; int flag; char NAME[MAXNAME]; if (headp->next == NULL) { printf("数据为空!\n"); return; } temp = headp; printf("请输入要查询的学生姓名:\n"); while (1) { temp = headp; fflush(stdin); scanf("%s", NAME); getchar(); while (temp != NULL) { if (strcmp(temp->data.name, NAME) == 0) break; temp = temp->next; } if (temp == NULL) { printf("错误!库中没有该学生的信息\n"); printf("键入'y'重新输入或'n'退出该功能\n"); while (1) { flag = 0; scanf("%c", &c); getchar(); if (c == 'y' || c == 'Y') { printf("请重新输入要查询学生的姓名\n"); break; } else if (c == 'n' || c == 'N') { flag = 1; break; } else printf("输入非法!请输入'y'或'n',不要输入其它字符\n"); } if (flag) break; } else { printf("\n\n%s的信息如下:\n\n", NAME); printf("%-10s %-8s %-10s %-10s %-10s %-10s %6s\n", s2, s3, s4, s5, s6, s7, s8); printf("%-10.2f %-10d", temp->data.aver, temp->data.sum); for (i = 0; i < MAXSUBJECT; i++) printf("%-12d", temp->data.score[i]); printf("\n"); break; } } } void Delete() { LIST temp = NULL, deletp = NULL; int flag; char NAME[MAXNAME]; if (headp->next == NULL) { printf("数据为空!\n"); return; } temp = headp; printf("请输入要删除的学生的姓名:\n"); // 现在这个情况,链表一定不为空 while (1) { temp = headp; fflush(stdin); scanf("%s", NAME); getchar(); // 搜索要删除的学生姓名所在结点的上一个 while (temp->next != NULL) { if (strcmp(temp->next->data.name, NAME) == 0) break; temp = temp->next; } if (temp->next == NULL) { flag = 0; printf("您要删除的学生不存在,键入'y'重新输入或'n'退出该功能\n"); while (1) { c = getchar(); getchar(); if (c == 'y' || c == 'Y') { printf("请重新输入学生姓名:\n"); break; } else if (c == 'n' || c == 'N') { flag = 1; break; } else printf("输入非法!请重新输入'y' or 'n'\n"); } if (flag) break; } else { // 要删除的结点是最后一个结点 if (temp->next->next == NULL) { free(temp->next); temp->next = NULL; } else { deletp = temp->next; temp->next = temp->next->next; free(deletp); } printf("\n删除成功!"); break; } } } void Ask() { fflush(stdin); printf("\n\n输入'n'结束该信息管理系统,或输入其它任意字符回到菜单\n"); scanf("%c", &c); getchar(); if (c == 'n') { printf("\nBye~ Have a good day! \n\n"); exit(EXIT_FAILURE); } } void AddUserInput() { int flag = 0, flag2 = 0; LIST newp = NULL; LIST temp = headp->next; printf("请输入学生姓名:\n"); while (1) { newp = (LIST)malloc(sizeof(NODE)); flag = 0; temp = headp->next; fflush(stdin); scanf("%s", newp->data.name); getchar(); while (temp != NULL) { if (strcmp(newp->data.name, temp->data.name) == 0) { flag = 1; break; } temp = temp->next; } if (flag) { printf("\n库中已有该名字,请退回到菜单选择\"更新信息\"或选择重新输入名字\n"); printf("是否重新输入?(y/n)\n"); while (1) { flag2 = 0; c = getchar(); getchar(); if (c == 'y') { printf("\n您选择了'y',请重新输入名字\n"); break; } else if (c == 'n') { flag2 = 1; break; } else { printf("\n请输入'y'或'n',不要输入其它字符!\n"); printf("请重新输入'y'或'n' \n"); } } if (flag2) break; } else { temp = headp; while (temp->next != NULL) temp = temp->next; temp->next = newp; newp->next = NULL; newp->data.sum = 0; newp->data.aver = 0.0; printf("请依次输入该学生语文、数学、英语、计算机、C语言,五门课的成绩\n"); for (i = 0; i < MAXSUBJECT; i++) { scanf("%d", &newp->data.score[i]); newp->data.sum += newp->data.score[i]; } newp->data.aver = newp->data.sum * 1.0 / MAXSUBJECT; printf("\n添加成功!\n"); printf("是否继续添加?(输入'n'结束该功能,输入其它任意字符继续添加)\n"); fflush(stdin); c = getchar(); getchar(); if (c == 'n') break; else printf("\n请继续输入要添加的学生的姓名\n"); } } } void AddFscanf(NODE newNode) { LIST newp = (LIST)malloc(sizeof(NODE)); LIST temp = headp; while (temp->next != NULL) temp = temp->next; temp->next = newp; newp->next = NULL; newp->data.sum = 0; newp->data.aver = 0.0; strcpy(newp->data.name, newNode.data.name); for (i = 0; i < MAXSUBJECT; i++) newp->data.score[i] = newNode.data.score[i]; newp->data.sum = newNode.data.sum; newp->data.aver = newNode.data.aver; } void Print() { LIST temp = NULL; if (headp->next == NULL) { printf("数据为空!\n"); return; } temp = headp; printf("已存储的数据为:\n"); SplitLine(); printf("%-15s %-10s %-8s %-10s %-10s %-10s %-10s %6s\n", s1, s2, s3, s4, s5, s6, s7, s8); while (temp->next != NULL) { printf("%-15s %-10.2f %-10d", temp->next->data.name, temp->next->data.aver, temp->next->data.sum); for (i = 0; i < MAXSUBJECT; i++) printf("%-12d", temp->next->data.score[i]); printf("\n"); temp = temp->next; } SplitLine(); } void SplitLine() { printf("\n========================================================================================\n\n"); } void Instructions() { printf("\n\n\t The Student's Grade Management System\n\n"); printf("---------------------Student Menu------------------------\n"); if (headp->next == NULL) { printf("* 1 输入学生信息\t\t\t * 0 退出学生系统\n"); printf("----------------------------------------------------------\n"); printf("此时数据为空!仅支持输入学生信息!\n"); printf("Enter your choice 0 or 1: "); } else { printf("* 1 输入学生信息\t\t\t * 2 删除学生信息\n"); printf("* 3 查询学生信息\t\t\t * 4 更新学生信息\n"); printf("* 5 排序学生信息\t\t\t * 6 保存学生信息\n"); printf("* 7 显示学生信息\t\t\t * 0 退出学生系统\n"); printf("----------------------------------------------------------\n"); printf("Enter your choice [0 - 9]: "); } scanf("%d", &choice); printf("\n\n"); }
    Processed: 0.011, SQL: 10