数据结构课程设计-学生信息管理
2015-12-24 10:51
901 查看
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<malloc.h> #define LEN sizeof(struct Student) struct Student //学生信息的结构体声明 { unsigned int num; //记录学号 char grade[10]; //记录年级 char name[20]; //记录姓名 char born[20]; //记录出生年月 char sex[10]; //记录性别 char poli[20]; //记录政治面貌 char phone[20]; //记录联络电话 char addr[100]; //记录家庭住址 struct Student *next; //指向下一个结构体的指针 }; struct Student *head = NULL; unsigned int kg = 0; //******************对各功能函数的声明*************************** void show(); //显示函数的声明 struct Student *input(); //新建学生信息的函数声明 struct Student *insert(struct Student *head,struct Student *stu); //插入学生信息的函数声明 struct Student *del(struct Student *head); //删除学生信息的函数声明 void alter(struct Student *head); //修改学生信息的函数声明 void search(struct Student *head,unsigned int num); //查询学生信息的函数声明 void output(struct Student *head); //保存学生信息的函数声明 //*************************************************************** void show() { int n,z = 1,k = 0; char cho; do { //***********显示提示信息********** printf(" 学生信息管理系统 \n"); printf(" \n"); printf(" 1.新建学生信息 \n"); //显示序号1的功能 printf(" 2.插入学生信息 \n"); //显示序号2的功能 printf(" 3.删除学生信息 \n"); //显示序号3的功能 printf(" 4.修改学生信息 \n"); //显示序号4的功能 printf(" 5.查询学生信息 \n"); //显示序号5的功能 printf(" 6.保存学生信息 \n"); //显示序号6的功能 printf(" 0.退出系统 \n"); //显示序号0的功能 printf(" \n"); printf(" \n"); //******************************** printf(" 请输入功能序号: "); //提示用户输入 while(!scanf("%d",&n)) //接受用户输入的功能序号,并且进行排错 { printf(" 输入序号有误,请重新输入: "); fflush(stdin); } printf("\n"); //输出回车 while((n < 0 || n > 6)) //对用户输入不能实现的功能序号进行处理 { printf(" 抱歉,没有此功能,请重新输入功能序号: "); //提示用户所输入的功能序号系统不能进行处理 fflush(stdin); while(!scanf("%d",&n)) //接收用户重新输入的功能序号 { printf(" 输入序号有误,请重新输入: "); fflush(stdin); } printf("\n"); //输出回车 } switch(n) //对用户信息进行功能函数的调用 { case 0: { printf(" "); if (k == 1) //对于没有对数据进行存盘的情况进行对用户提示以确认是否退出 { printf("数据未保存,是否退出? Y.是 N.否 请选择: "); fflush(stdin); cho = getchar(); if (cho == 'y' || cho == 'Y') { z = 0; printf(" "); } else if (cho == 'n' || cho == 'N') {} else { printf(" 无效输入\n "); system("pause"); } } else { z = 0; } break; } case 1: { head = input(); k = 1; system("pause"); break; } case 2: { head = insert(head,NULL); k = 1; printf(" 成功插入学生信息\n "); system("pause"); break; } case 3: { head = del(head); k = 1; printf(" "); system("pause"); break; } case 4: { alter(head); break; } case 5: { if (head == NULL) k = 1; search(head,0); printf(" "); system("pause"); break; } case 6: { k = 0; output(head); break; } } }while(z == 1); } //*************************************************************** struct Student *input() { struct Student *p1,*p2; unsigned m,n,i; FILE *read; char filename[20]; head = NULL; printf(" 请输入学生人数: "); while (!scanf("%u",&n)) //接收录入学生信息的人数,并对输入有误的进行排除 { printf(" 输入有误,请重新输入学生人数: "); fflush(stdin); } if (n == 0) //对录入人数为0的情况进行处理 { printf(" 学生个数为0人,建立失败\n "); return (head); } head = p2 = p1 = (struct Student *) malloc (LEN); //开辟内存,用于生成链表 printf(" 学生个数为:%u个,请按照以下顺序输入\n",n); //对学生总数的提示,并且提示每个学生信息的输入顺序 printf(" 学号、年级、姓名、出生年月、性别、政治面貌、联络电话、家庭住址\n"); //每个学生信息的输入顺序 for(i = 0; i < n; i++) { printf(" 请输入第%u个学生信息!\n",i+1); //提示接下来要输入第几个学生的信息 printf(" "); //格式调整,输出三个空格 fflush(stdin); while(!scanf("%d %s %s %s %s %s %s %s",&p2->num,p2->grade,p2->name,p2->born,p2->sex,p2->poli,p2->phone,p2->addr)) { printf(" 输入有误,请重新输入该学生信息\n "); fflush(stdin); } if (n == 1) //对录入人数为1时的情况进行处理 { p2->next = NULL; } else //对录入人数大于1的情况进行录入,并在录入时进行排序,每录入一位学生信息就开辟一个内存空间,用于下一个学生的录入 { head = insert(head,p2); p2 = (struct Student *) malloc (LEN); } } printf(" 成功录入学生信息,并且学生信息已经按学号从小到大排列\n"); printf(" 学生信息如下: \n"); search(head,1); //以表格的形式显示所录入的学生信息 printf(" "); return head; //返回*head指针的地址 } struct Student *insert(struct Student *head,struct Student *stu) //插入学生信息功能函数定义 { struct Student *p1,*p2; if (stu == NULL) //对于传入插入学生信息为空时要求用户输入插入的学生信息 { printf(" 请按照学号、年级、姓名、出生年月、性别、政治面貌、联络电话、家庭住址的顺序输入\n "); //每个学生信息的输入顺序 stu = (struct Student *) malloc (LEN); while(!scanf("%d %s %s %s %s %s %s %s",&stu->num,stu->grade,stu->name,stu->born,stu->sex,stu->poli,stu->phone,stu->addr)) { printf(" 输入信息有误,请重新输入\n"); fflush(stdin); } } if (head == NULL) //对于链表为空的情况的处理 { head = stu; head->next = NULL; } else //在链表中插入学生信息 { p1 = p2 = head; while(stu->num > p2->num && p1->next != NULL) //查找适合位置的前一个学生 { p2 = p1; p1 = p1->next; } if (p2 == p1) //插入的学生正好为链表头的情况 { if (stu->num < p2->num) //插入在表头前 { head = stu; stu->next = p2; } else //插入在表头后 { p2->next = stu; stu->next = NULL; } } else //插入的学生在链表中的情况 { if (stu->num < p1->num) //插入到p1指向的学生前 { p2->next = stu; stu->next= p1; } else //插入到p1指向的学生后 { p1->next = stu; stu->next = NULL; } } } kg = 1; return(head); } struct Student *del(struct Student *head) //删除学生信息的功能函数定义 { unsigned int num,k; struct Student *p1,*p2; if (head == NULL) //对空链表删除的情况处理 { printf(" 没有学生信息,结束删除\n"); return(head); } printf(" 请输入要删除的学生学号: "); //求用户输入要删除的学生学号 while(!scanf("%u",&num)) //接收学生序号并进行排错处理 { printf(" 输入有误,请重新输入学生序号: "); fflush(stdin); } do { p1 = p2 = head; while(num != p1->num && p1->next != NULL) //查找删除位置的前一个学生 { p2 =p1; p1= p1->next; } if (num == p1->num) //对满足要求的学生进行删除 { if (num == p1->num) { if (p1->next == NULL && p1 == head) //对只有一个节点的链表进行删除 { free(p1); head = NULL; } else if (p1->next == NULL) //删除链表尾节点 { free(p1); p2->next = NULL; } else if (head == p1) //删除表头节点 { head = p1->next; free(p1); } else //删除表中节点 { p2->next = p1->next; free(p1); } } printf(" 成功删除学生信息\n"); //提示删除成功信息 } else //找不到要删除的学生时的提示 { printf(" 找不到该同学信息\n"); fflush(stdin); } if (head == NULL) //对空链表删除时的处理 { printf(" 没有学生信息,结束删除\n"); return(head); } else //提示用户删除后是否继续 { printf(" 1.继续删除学生信息\n"); printf(" 2.结束删除\n"); printf(" 请选择: "); while(!scanf("%u",&k)) //接收用户选择 { printf(" 输入有误,请重新输入选择的序号: "); fflush(stdin); } if (k == 1) //选择继续 { printf(" 请输入要删除的学生学号: "); while(!scanf("%u",&num)) { printf(" 输入有误,请重新输入学生学号: "); fflush(stdin); } } else if (k != 2) //对于不是选择2的继续循环提示 { k = 1; } } }while(k == 1); return(head); //返回表头地址 } void search(struct Student *head,unsigned int num) //查询函数的定义 { unsigned int cho,t = 0; struct Student *p1; if (head == NULL) //对查询空链表时的操作 { printf(" 没有学生信息,结束查询\n"); return; } p1 = head; if (num == 0) //当传入实参 num = 0 需要接受用户需要的查询方式(个别或者全部),不等于0则可以直接查询个别学生信息 { printf(" 1.查询个别学生信息\n"); printf(" 2.查询全部学生信息\n"); printf(" 请选择: "); while(!scanf("%u",&cho)) //对错误输入数据的处理 { printf(" 输入有误,请重新输入序号: "); fflush(stdin); } while(cho != 1 && cho != 2) //处理不能处理的功能序号 { printf(" 抱歉,没有此功能,请重新输入功能序号: "); //提示不能处理的信息,并要求用户重新输入功能序号 while(!scanf("%u",&cho)) //接收用户重新输入的功能序号 { printf(" 输入序号有误,请重新输入序号: "); fflush(stdin); } printf("\n"); //输出回车 } } else { cho = 1; //设置直接查询个别学生的开关 } if (kg == 1) //kg(全局变量)为全部学生查询的开关 kg = 1 打开开关由下面直接进行全部学生查询 kg = 0 关闭开关 { cho = 2; } switch(cho) //查询类别分支 { case 1: //查询个别学生 { do { p1 = head; if (num == 0 || t == 1) { printf(" 请输入需要查询的学生学号: "); while(!scanf("%u",&num)) { printf(" 输入有误,请重新输入: "); fflush(stdin); } t = 1; //打开开关,该开关为查询完毕后 num不能作为该分支的条件(因为以下的操作会改变num的值)而建立的,并且能够实现当传入num不等于0时,以下询问用户是否继续的分支就不用执行了 } else { cho = 2; //如果传入的实参num不等于0 则该 DO WHILE 循环只做一次 } while(p1->num != num) //查找查询学生学号 { if (p1->next == NULL) break; p1 = p1->next; } if (p1->num == num) //查找成功一表格方式输出该学生信息 { //***********************表格头部设计************************ printf(" ┃学号┃年级┃ 姓名 ┃出生年月┃性别┃政治面貌┃ 联络电话 ┃ 家庭住址 ┃\n"); //********************************************************** //****************表格主体设计以及数据输出****************** printf(" ┃%-4d┃%-4s┃%-8s┃%-8s┃%-4s┃%-8s┃%-12s┃%-38s┃\n",p1->num,p1->grade,p1->name,p1->born,p1->sex,p1->poli,p1->phone,p1->addr); //********************************************************** //***********************表格头部设计*********************** //********************************************************* } else //查找不成功,提示用户找不到该学生 { printf(" 找不到该学生\n"); } if (t == 1) //如果传入的num=0,则此分支有效,询问用户是否继续查询 { printf(" 1.继续查询\n"); printf(" 2.结束查询\n"); printf(" 请选择: "); while(!scanf("%u",&cho)) //对输入序号查错,利用cho = 2时的情况跳出 DO WHILE 循环 { printf(" 输入序号有误,请重新输入: "); fflush(stdin); } } }while (cho == 1); break; } case 2: //查询全部信息 { //***********************表格头部设计************************ printf(" ┃学号┃年级┃ 姓名 ┃出生年月┃性别┃政治面貌┃ 联络电话 ┃ 家庭住址 ┃\n"); //********************************************************** //****************表格主体设计以及数据输出****************** while(p1 != NULL) { //intf(" ┣━━╋━━╋━━━━╋━━━━╋━━╋━━━━╋━━━━━━╋━━━━━━━━━━━━━━━━━━━┫\n"); printf(" ┃%-4d┃%-4s┃%-8s┃%-8s┃%-4s┃%-8s┃%-12s┃%-38s┃\n",p1->num,p1->grade,p1->name,p1->born,p1->sex,p1->poli,p1->phone,p1->addr); p1 = p1->next; } //********************************************************** //***********************表格头部设计*********************** //********************************************************** break; } } if (kg == 1) kg = 0; //关闭查询全部学生的开关,以便下一次使用 } void alter(struct Student *head) //修改学生信息的功能函数定义 { struct Student *p1,*p2; unsigned int num,cho,k,l=0; if (head == NULL) //对空链表的处理 { printf(" 没有学生信息,结束修改\n "); system("pause"); return; } printf(" 请输入需要修改的学生学号: "); while(!scanf("%u",&num)) //接受用户输入的学号并且进行查错 { printf(" 输入学号有误,请重新输入: "); fflush(stdin); } do { p2 = p1 = head; while(p1->num != num) //查找学生学号 { if (p1->next == NULL) break; p2 = p1; p1 = p1->next; } if (p1->num == num) //查找成功 { printf(" 已找到该学生,该学生的信息为: \n"); search(head,num); l = 0; do { if (l == 0) //开关,当第一次循环时 l=0 执行 IF 语句 printf(" 选择修改的内容\n"); else printf(" 序号输入错误,请重新选择\n"); l = 1; //打开开关,以在以下操作用户输入序号超出范围时控制上面的分支语句,进而可以更好地向用户提示信息 printf(" 1.学号\n"); printf(" 2.年级\n"); printf(" 3.姓名\n"); printf(" 4.出生年月\n"); printf(" 5.性别\n"); printf(" 6.政治面貌\n"); printf(" 7.联络电话\n"); printf(" 8.家庭住址\n"); printf(" 9.全部\n"); printf(" 请选择序号: "); fflush(stdin); while(!scanf("%u",&cho)) //接受序号并查错 { printf(" 输入序号有误,请重新输入: "); fflush(stdin); } }while(cho > 9 || cho < 1); switch(cho) //对序号进行多分支处理 { case 1: { printf(" 请输入该学生改正的学号信息: "); while(!scanf("%u",&p1->num)) { printf(" 输入改正信息有误,请重新输入: "); fflush(stdin); } break; } case 2: { printf(" 请输入该学生改正的年级信息: "); while(!scanf("%s",p1->grade)) { printf(" 输入改正信息有误,请重新输入: "); fflush(stdin); } break; } case 3: { printf(" 请输入该学生改正的姓名信息: "); while(!scanf("%s",p1->name)) { printf(" 输入改正信息有误,请重新输入: "); fflush(stdin); } break; } case 4: { printf(" 请输入该学生改正的出生年月信息: "); while(!scanf("%s",p1->born)) { printf(" 输入改正信息有误,请重新输入: "); fflush(stdin); } break; } case 5: { printf(" 请输入该学生改正的性别信息: "); while(!scanf("%s",p1->sex)) { printf(" 输入改正信息有误,请重新输入: "); fflush(stdin); } break; } case 6: { printf(" 请输入该学生改正的政治面貌信息: "); while(!scanf("%s",p1->poli)) { printf(" 输入改正信息有误,请重新输入: "); fflush(stdin); } break; } case 7: { printf(" 请输入该学生改正的联络电话信息: "); while(!scanf("%s",p1->phone)) { printf(" 输入改正信息有误,请重新输入: "); fflush(stdin); } break; } case 8: { printf(" 请输入该学生改正的家庭住址信息: "); while(!scanf("%s",p1->addr)) { printf(" 输入改正信息有误,请重新输入: "); fflush(stdin); } break; } case 9: { printf(" 请输入该学生全部要改正的信息: "); while(!scanf("%u %s %s %s %s %s %s %s",&p1->num,p1->grade,p1->name,p1->born,p1->sex,p1->poli,p1->phone,p1->addr)) { printf(" 输入改正信息有误,请重新输入: "); fflush(stdin); } break; } } if (cho == 1 || cho == 9) //对修改过学号的学生进行重新排序 { if (p1 == head) //当该学生在链表头时,删除链表头节点 { head = head->next; } else if (p1->next == NULL) //当该学生在链表尾时,删除链表尾节点 { p2->next = NULL; } else //当该学生在链表中时,删除该学生对应的节点 { p2->next = p1->next; } head = insert(head,p1); //利用插入学生信息功能函数,进行该学生的重新排序 } printf(" 修改成功,该学生改正后的信息为: \n"); search(head,p1->num); //显示以下修改后的学生信息 //询问用户是否继续 printf(" 1.继续修改其他学生信息\n"); printf(" 2.退出修改\n"); printf(" 请选择: "); while(!scanf("%u",&k)) //接受用户输入的序号,并进行排错 { printf(" 输入序号有误,请重新输入: "); fflush(stdin); } if (k == 1) //接受下一次修改的学生学号 { printf(" 请输入需要修改的学生学号: "); while(!scanf("%u",&num)) { printf(" 输入修改信息有误,请重新输入: "); fflush(stdin); } } else if (k != 2) //排错 { printf(" 输入有误,请重新输入\n"); } } else //查找不到学生时要求用户进行重新输入学生序号 { k = 1; printf(" 找不到该学生信息,请重新输入需要修改的学生学号: "); fflush(stdin); while(!scanf("%u",&num)); //接受用户重新输入的学号并进行排错 { printf(" 输入修改信息有误,请重新输入: "); fflush(stdin); } } }while(k == 1); printf(" "); system("pause"); } void output(struct Student *head) //保存学生信息到txt文件功能函数 { FILE *write; char filename[20]; struct Student *p1,*p2; unsigned int cho,n; if (head == NULL) //对空链表进行处理 { printf(" 没有学生信息,保存失败\n "); system("pause"); return; } p1 = p2 = head; printf(" 请输入保存的文件名(如save): "); while(!scanf("%s",filename)) //接受文件名,并进行排错(几乎不会出现错误的现象,慎重而设) { printf(" 输入的文件名有误,请重新输入:"); fflush(stdin); } strcat(filename,".txt"); //链接后缀名 write = fopen(filename,"w"); //以写入方式打开文件 //询问用户用哪种方式保存 printf(" 1.以表格形式保存(不可重新录入)\n"); printf(" 2.以输入形式保存(可重新录入)\n"); printf(" 请选择: "); while(!scanf("%u",&cho)) //接受用户输入的序号并进行排错 { printf(" 输入序号有误,请重新输入: "); fflush(stdin); } while(cho < 1 || cho > 2) //对超出范围的序号进行排错 { printf(" 输入序号有误,请重新输入: "); while(!scanf("%u",&cho)) { printf(" 输入序号有误,请重新输入: "); //对输入错误的序号进行排错 fflush(stdin); } } if (cho == 1) //以表格形式保存 { //***********************表格头部设计************************ fprintf(write," ┃学号┃年级┃ 姓名 ┃出生年月┃性别┃政治面貌┃ 联络电话 ┃ 家庭住址 ┃\n"); //********************************************************** //****************表格主体设计以及数据输出****************** while(p1 != NULL) { ; fprintf(write," ┃%-4d┃%-4s┃%-8s┃%-8s┃%-4s┃%-8s┃%-12s┃%-38s┃\n",p1->num,p1->grade,p1->name,p1->born,p1->sex,p1->poli,p1->phone,p1->addr); p1 = p1->next; } //********************************************************** //***********************表格头部设计*********************** //********************************************************** } else //以输入的格式保存 { n = 0; fprintf(write," \n"); //为输出学生人数留位置 while(p1 != NULL) { fprintf(write,"%u %s %s %s %s %s %s %s\n",p1->num,p1->grade,p1->name,p1->born,p1->sex,p1->poli,p1->phone,p1->addr); p1 = p1->next; n++; //每向文件输出一位学生信息n就累加1 } fseek(write,0,SEEK_SET); //移到文件头部 fprintf(write,"%u",n); //写入学生个数 } fclose(write); printf(" 保存成功\n "); system("pause"); } int main() { show(); //调用显示功能函数 }
相关文章推荐
- 数据结构课程设计——学生成绩管理系统
- c++ 数据结构 *** 哈夫曼树的应用——压缩软件
- 数据结构和算法经典100题-第25题
- 算法与数据结构总结
- 2-7-集合运算(A-B)∪(B-A)-线性表-第2章-《数据结构》课本源码-严蔚敏吴伟民版
- 2-6-静态链表-线性表-第2章-《数据结构》课本源码-严蔚敏吴伟民版
- 严蔚敏数据结构顺序表的所有基本操作
- java数据结构--二叉树,递归遍历,非递归遍历,层次遍历
- 二叉树的先序、中序和后序遍历(总结)
- 数据结构实验之排序四:寻找大富翁
- 数据结构与算法 LeetCode编程练习--counts Prime
- 数据结构之图(邻接表存储,DFS和BFS遍历)
- 严蔚敏数据结构单链表的所有基本操作
- 2-5-归并链式存储的单链表-线性表-第2章-《数据结构》课本源码-严蔚敏吴伟民版
- 数据结构之链表
- 【Educational Codeforces Round 3 E】【树链剖分】Minimum spanning tree for each edge 图构最小生成树,生成树必须包含第i条边
- 2-路插入排序
- 数据结构实验之排序六:希尔排序 【OJ--3403】
- 2-4-单链表链式存储结构-线性表-第2章-《数据结构》课本源码-严蔚敏吴伟民版
- 数据结构算法1------算法和算法分析