#include <string.h> #include <stdio.h> #include <stdlib.h> #define _COURSES 3//定义科目数 #define _LEN sizeof(student)//定义结构体大小 //枚举返回值情况 enum status { OVERFLOW = -1, //内存(溢出)问题 DONE = 0, //成功 NOFOUND = 1, //不存在 OPENFAIL = 2, //打开(文件)失败 BACK = 3 //返回 }; //end //定义学生信息结构体 typedef struct StudentInfo { //数据域 unsigned int num;//学号 char name[11];//姓名 float scores[_COURSES];//各科成绩 //指针域 struct StudentInfo *next;//存放下一节点的地址 }student; //end student *head=NULL;//声明链表头结点 student *curr=NULL;//声明指向当前节点的指针 int total = 0;//声明当前节点个数 int init();//初始化链表 int add_stu();//添加新节点 int show_all();//显示所有学生信息 int find_stu();//查找指定信息节点 int modify_stu();//修改指定信息节点 int remove_stu();//删除指定信息节点 int sort_list();//对链表排序 int save_to_file();//将所有信息保存至文件 int read_from_file();//从文件中读取信息 void about();//关于 int quit();//释放所有节点空间 int entering(student *input);//录入学生信息 void show_stu(student *show, int serial);//显示指定学生信息 void start();//程序开始界面 void change(student *former, student *latter, student *temp);//交换两个节点的数据域 void main() { int choice=0; init(); while(1) { system("cls"); start(); printf("请选择:"); scanf("%d",&choice); fflush(stdin);//清空缓冲区 switch (choice) { case 1: { add_stu(); break; } case 2: { show_all(); break; } case 3: { find_stu(); break; } case 4: { modify_stu(); break; } case 5: { remove_stu(); break; } case 6: { sort_list(); break; } case 7: { save_to_file(); break; } case 8: { read_from_file(); break; } case 9: { about(); break; } case 0: { quit(); exit(0); break; } default:{break;} } system("pause"); } } /*******************************************************/ /*功能: 初始化带头结点的链表,头结点指针域置空 */ /* */ /*返回: */ /*******************************************************/ int init() { head = (student *)malloc(_LEN);//为头结点申请空间 if (!head) {//如果申请空间失败,返回 return OVERFLOW; } head->next = NULL;//指向下一节点(空) curr = head->next;//当前节点指针指向第一个结点 total = 0;//当前节点个数初始化为0(头结点不计算在内) return DONE; } /*******************************************************/ /*功能:头插法添加新节点,并刷新学生人数 */ /* */ /*返回: */ /*******************************************************/ int add_stu() { student *add = (student *)malloc(_LEN); curr = head->next;//当前节点指针指向第一个节点 printf("\t====当前已存入 %d 个同学\n",total); printf("请输入第 %d 个学生的信息\n",total+1); if (BACK == entering(add)) { free(add); return BACK; } head->next = add;//头结点指针域指向新建的节点 add->next = curr;//新建节点指针域指向第一个节点 curr = add; //当前节点指向新建的节点 total += 1; //更新学生总人数 return DONE; } /*******************************************************/ /*功能:显示所有学生信息 */ /* */ /*返回: */ /*******************************************************/ int show_all() { if ( 0 == total ) { printf("\t====没有可供显示的学生信息!\n"); return NOFOUND; } curr = head->next;//当前节点指针指向第一个节点 printf("\t%4s%12s%12s","序号","学号","姓名"); for (int m=0; m<_COURSES; m++) { printf("%7s","科目"); } printf("\n"); printf("\t-------------------------------------------------------------\n"); for (int i=1; i<=total; i++) { show_stu(curr,i); curr = curr->next;//当前节点指针后移 } printf("\t-------------------------------------------------------------\n"); return DONE; } /*******************************************************/ /*功能:查找指定学生信息 */ /* */ /*返回: */ /*******************************************************/ int find_stu() { char stu_name[11]; int flag=1; printf("请输入要查找的学生姓名:"); scanf("%s",stu_name); curr = head->next;//指向第一个节点 while (curr != NULL) { if (strcmp(stu_name,curr->name) == 0) { printf("\t%4s%12s%12s","序号","学号","姓名"); for (int m=0; m<_COURSES; m++) { printf("%7s","科目"); } printf("\n"); printf("\t-------------------------------------------------------------\n"); show_stu(curr,flag); return DONE; } curr = curr->next; ++flag; } printf("\t====没有找到 %s !请仔细核对姓名再查找\n",stu_name); return NOFOUND; } /*******************************************************/ /*功能:修改指定学生的所有信息 */ /* */ /*返回: */ /*******************************************************/ int modify_stu() { char stu_name[11]; int flag=1; curr = head->next;//指向第一个节点 printf("请输入要修改的学生的姓名:"); scanf("%s",stu_name); while (curr != NULL) { if (strcmp(stu_name,curr->name) == 0) { printf("\t%4s%12s%12s","序号","学号","姓名"); for (int m=0; m<_COURSES; m++) { printf("%7s","科目"); } printf("\n"); printf("\t-------------------------------------------------------------\n"); show_stu(curr,flag); entering(curr); printf("\t====成功修改了 %s 的所有信息!\n",stu_name); return DONE; } curr = curr->next; ++flag; } printf("\t====没有找到 %s !请仔细核对姓名\n",stu_name); return NOFOUND; } /*******************************************************/ /*功能:删除指定学生 */ /* */ /*返回: */ /*******************************************************/ int remove_stu() { student *pre=head; char stu_name[11]; curr = head->next;//指向第一个节点 printf("请输入要删除的学生的姓名:"); scanf("%s",stu_name); while (curr != NULL) { if (strcmp(stu_name,curr->name) == 0) { pre->next = curr->next; // free(curr); // --total; // printf("\t====已成功删除\"%s\"\n",stu_name); return DONE; } pre = pre->next; curr = curr->next; } printf("\t====没有找到 %s !请仔细核对姓名\n",stu_name); return NOFOUND; } /*******************************************************/ /*功能:对所有学生排序 */ /* */ /*返回: */ /*******************************************************/ int sort_list() { student *temp = (student *)malloc(_LEN); student *curr_i = head->next; student *curr_j = NULL; char choice='0'; printf("\t \t1----按学号排序 .\t2----按姓名排序 . \n"); printf("\t \t3----按科目排序 .\t0----退 出 排 序. \n"); printf("请选择:"); scanf("%c",&choice); fflush(stdin); switch (choice) { case '1': { while(curr_i->next != NULL) { curr_j = curr_i->next; while (curr_j != NULL) { if (curr_i->num > curr_j->num) { change(curr_i,curr_j,temp); } curr_j = curr_j->next; } curr_i = curr_i->next; } printf("\t====排序成功!\n"); break; } case '2': { while(curr_i->next != NULL) { curr_j = curr_i->next; while (curr_j != NULL) { if (strcmp(curr_i->name , curr_j->name) > 0) { change(curr_i,curr_j,temp); } curr_j = curr_j->next; } curr_i = curr_i->next; } printf("\t====排序成功!\n"); break; } case '3': { while(curr_i->next != NULL) { curr_j = curr_i->next; while (curr_j != NULL) { if (curr_i->scores[0] < curr_j->scores[0]) { change(curr_i,curr_j,temp); } curr_j = curr_j->next; } curr_i = curr_i->next; } printf("\t====排序成功!\n"); break; } case '0': { free(temp); return BACK; } default: {printf("\t====输入有误!\n");break;} } free(temp); return DONE; } /*******************************************************/ /*功能:保存数据到文件 */ /* */ /*返回: */ /*******************************************************/ int save_to_file() { curr=head->next; if (total == 0) { printf("\t====目前还没有任何信息,不用保存!\n"); return BACK; } FILE *fp; if((fp=fopen("record.dat","wb"))==NULL) { printf("\t====文件打开失败!\n"); return OPENFAIL; } while (curr != NULL) { //将数据成块写入文件 fwrite((char *)curr, _LEN, 1, fp); curr=curr->next; } fclose(fp); printf("\t====信息已成功保存至文件\"record.dat\"文件中\n"); return DONE; } /*******************************************************/ /*功能:从文件中读取数据 */ /* */ /*返回: */ /*******************************************************/ int read_from_file() { char judge='y'; FILE *fp; if((fp=fopen("record.dat","r"))==NULL) { printf("文件不存在或者打开失败!\n"); return OPENFAIL; } printf("\t====读取文件会覆盖当前信息!是否确定载入文件?(y/n):"); scanf("%c",&judge); if (judge=='n' || judge=='N') { return BACK; } quit();//释放以前所有信息的空间 init();//重新初始化链表 curr = head;//当前节点指针指向头结点 student *add=(student *)malloc(_LEN);//申请空间存放读取的信息 while (fread((char *)add, _LEN, 1, fp)) {//由于存储的信息是最新的信息在前,所以读取的时候将其添加在链表尾 add->next=curr->next; curr->next=add; curr=add; add=(student *)malloc(_LEN); ++total; } fclose(fp); printf("\t====文件载入成功!当前已有%d个学生。\n",total); return DONE; } /*******************************************************/ /*功能: */ /* */ /*返回: */ /*******************************************************/ void about() { printf("\t#############################################################\n"); printf("\n\t \t欢迎各位用户反馈Bug或提出宝贵的意见和建议 \n"); printf("\t \t联系方式 \n"); printf("\t \t手 机:13667102098 \n"); printf("\t \tE-mail:[email protected] \n"); printf("\n\t \t\tC语言学生成绩管理系统1.0版\n\n"); printf("\t#############################################################\n"); } /*******************************************************/ /*功能:释放内存 */ /* */ /*返回: */ /*******************************************************/ int quit() { curr =head->next; student *temp=curr; while(curr != NULL) { temp=curr->next; free(curr); curr=temp; } curr=NULL; temp=NULL; free(head);//释放头节点 return DONE; } ////////////////////////////////////////////////////////////////////////// /*******************************************************/ /*功能:录入一个学生的全部信息 */ /* */ /*返回: */ /*******************************************************/ int entering(student *input) { printf("\n请输入学生的学号(输入0退出添加):"); scanf("%d",&input->num); if (0 == input->num) { return BACK; } printf("请输入学生的姓名(五个汉字以内):"); scanf("%s",&input->name); printf("请输入%d门科目的成绩(用空格隔开):", _COURSES); for (int i=0; i<_COURSES; i++) { scanf("%f",&input->scores[i]); } return DONE; } /*******************************************************/ /*功能:显示指定学生的所有信息 */ /* */ /*返回: */ /*******************************************************/ void show_stu(student *show, int serial) { printf("\t%4d%12d%12s",serial,show->num,show->name); for (int i=0; i<_COURSES; i++) { printf("%7.1f",show->scores[i]); } printf("\n"); } /*******************************************************/ /*功能:根据权限进入不同的界面 */ /* */ /*返回: */ /*******************************************************/ void start() { printf("\n"); printf("\t\t\t欢迎使用学生成绩管理系统\n"); printf("\t*************************************************************\n"); printf("\t|\t1----添 加 学 生.\t2----显 示 信 息. |\n"); printf("\t|\t3----查 找 学 生.\t4----修 改 信 息. |\n"); printf("\t|\t5----删 除 学 生.\t6----学 生 排 序. |\n"); printf("\t|\t7----信 息 存 档.\t8----读 取 存 档. |\n"); printf("\t|\t9----关 于.\t0----退 出. |\n"); printf("\t*************************************************************\n"); } /*******************************************************/ /*功能: */ /* */ /*返回: */ /*******************************************************/ void change(student *former, student *latter,student *temp) { *temp = *former; strcpy(former->name , latter->name); strcpy(latter->name , temp->name); former->num = latter->num; latter->num = temp->num; for (int i=0; i<_COURSES; i++) { former->scores[i] = latter->scores[i]; latter->scores[i] = temp->scores[i]; } }