运行效果
D:wangcCLionProjects est1212cmake-build-debug est1212.exe 【学生管理系统2.0】 ★————————————————————————————————————————★ | 1. 信息录入 2. 成绩录入 3. 信息查询 | | 4. 成绩查询 5. 删除信息 6. 信息追加 | | 7. 更改分数 8. 查看排名 9. 成绩分段 | | 10.保存文件 11.文件输出 12.文件导入 | ★————————————————按0并回车退出——————————————————★ 请输入执行数字:1 *****************************************************信息录入*********************************************************** 依次键入学号、姓名、性别、宿舍号码、电话号码,用一个【空格】隔开各数据,每一条输入完成后按回车键进行下一条输入。 【退出请输入'0'并回车】 样例: 541913460230 张三 男 1717 66666 在此输入: 1001 张三丰 男 521 888888 1001 张三丰 男 521 888888 1002 李四 男 522 555555 1002 李四 男 522 555555 0 0 请输入执行数字:3 请在此输入:1002 1002 输入了错误的第一次选择数字!重新输入: 3 3 输入了错误的第一次选择数字!重新输入: 0 0 输入了错误的第一次选择数字!重新输入: 1 1 通过学号(输入1),姓名(输入2):1 1 输入学号(输入0并回车结束):1001 1001 学号:1001 姓名:张三丰 性别:男 宿舍号码:521 电话号码:888888 输入学号(输入0并回车结束):
源码
#include#include #include #include #define LEN sizeof(struct student) struct student { char num[20];//学号 char name[20];//姓名 char sex[20];//性别 char room[20];//宿舍号码 char tel[20];//电话号码 char CHN[20];//语文 char MATH[20];//数学 char ENG[20];//英语 char PE[20];//体育 char PRO[20];//专业 char average_score[20];//平均分 struct student *next; }; int n;//节点数 struct student *creat();//信息录入 void score(struct student *head);//成绩录入 void findinformation(struct student *head);//信息查询 void findscore(struct student *head);//成绩查询 struct student *del(struct student *head);//信息删除 struct student *insert(struct student *head);//信息插入 void update(struct student *head);//修改分数 void Oscore(struct student*head);//排序输出 void swap(struct student*p1,struct student*p2);//交换数据 void fenduan(struct student*head);//分段输出 int checknum(char ch[]);//检查纯数字的数据里是否混入了非数字的非法输入 int transformint(char ch[]);//纯数字整数(字符串转向int类型) void save(struct student *head); //文件存储 void export1();//文件输出 struct student *import();//文件导入 int checkscore(char ch[]);//检查分数是否为0-99的纯数字 int IncludeChinese(char *str); //检查性名、性别是否包含汉字 int main() { //微信关注公众号:C语言中文社区,免费领取更多 struct student *head=NULL; char choose[20]; menu://设置主菜单的点 printf(" "); printf(" 【学生管理系统2.0】 "); printf(" ★————————————————————————————————————————★ "); printf(" | 1. 信息录入 2. 成绩录入 3. 信息查询 | "); printf(" | 4. 成绩查询 5. 删除信息 6. 信息追加 | "); printf(" | 7. 更改分数 8. 查看排名 9. 成绩分段 | "); printf(" | 10.保存文件 11.文件输出 12.文件导入 | "); printf(" ★————————————————按0并回车退出——————————————————★ "); printf("请输入执行数字:"); while(scanf("%s",choose)&&checknum(choose)==0)//检查到不是纯数字 让用户重新输入 { printf("输入无效,重新输入:"); } switch(transformint(choose)) { case 1: head=creat(); break; case 2: score(head); break; case 3: findinformation(head); break; case 4: findscore(head); break; case 5: head=del(head); break; case 6: head=insert(head); break; case 7: update(head); break; case 8: Oscore(head); break; case 9: fenduan(head); break; case 10: save(head); break; case 11: export1(); break; case 12: head=import(); break; } if(transformint(choose)<0||transformint(choose)>12)//输入了不在执行数字范围内的数字返回主菜单的点 { system("cls");//清理屏幕和缓冲区 fflush(stdin); goto menu; } if(transformint(choose)!=0)//输入不是0,继续回到主菜单 { goto menu; } system("cls");//结束时清理屏幕和缓冲区,打印下方的校徽 fflush(stdin); printf(" 感谢使用! "); printf(" * "); printf(" * *** **** "); printf(" *** **** **** "); printf(" **** **** **** **** "); printf(" **** **** **** **** "); printf(" **** **** **** **** "); printf(" **** **** **** **** "); printf(" **** **** **** **** "); printf(" **** ******* **** "); printf(" ************* "); printf(" ***** "); system("pause"); return 0; } struct student *creat()//录入信息,创建链表 { system("cls"); fflush(stdin); printf("*****************************************************信息录入*********************************************************** "); printf("依次键入学号、姓名、性别、宿舍号码、电话号码,用一个【空格】隔开各数据,每一条输入完成后按回车键进行下一条输入。 "); printf(" 【退出请输入'0'并回车】 "); printf("样例: 541913460230 张三 男 1717 66666 在此输入: "); n=0; struct student *head,*p1,*p2; head = NULL; p1=p2=(struct student*)malloc(LEN); while(scanf("%s",p1->num)&&checknum(p1->num)==0) { printf("输入错误的学号,重新输入: "); } if(transformint(p1->num)==0)//输入了0退出函数调用,传回去表头指针head给主函数的head { system("cls"); fflush(stdin); return(head); } while(scanf("%s",p1->name)&&IncludeChinese(p1->name)==0)//这几行while(scanf)都是具有容错的输入,整个程序中都存在输入容错!!! { printf("输入错误的名字,重新输入: "); } while(scanf("%s",p1->sex)&&IncludeChinese(p1->sex)==0) { printf("输入错误的性别,重新输入: "); } while(scanf("%s",p1->room)&&checknum(p1->room)==0) { printf("输入错误的宿舍号码,重新输入: "); } while(scanf("%s",p1->tel)&&checknum(p1->tel)==0) { printf("输入错误的手机号码,重新输入: "); } printf(" "); while(transformint(p1->num)!=0)//输入每个节点的学号不是0的时候开始循环。 { n+=1;//节点+1 if(n==1) //PS:此处为建立链表常规过程(参考了谭浩强C程序设计第九章链表,红皮那本) { head=p1;//第一个节点 表头指向上面开辟的第一个节点 p1 p2 head都指向此处此时 }else { p2->next=p1;//后面的节点,p2的next指向p1将两个节点连接到一起 p2=p1;//p2再跟p1 } p1=(struct student*)malloc(LEN);//p1指向开辟的新节点 while(scanf("%s",p1->num)&&checknum(p1->num)==0) { printf("输入错误的学号,重新输入: "); } if(transformint(p1->num)==0) { break; } while(scanf("%s",p1->name)&&IncludeChinese(p1->name)==0) { printf("输入错误的名字,重新输入: "); } while(scanf("%s",p1->sex)&&IncludeChinese(p1->sex)==0) { printf("输入错误的性别,重新输入: "); } while(scanf("%s",p1->room)&&checknum(p1->room)==0) { printf("输入错误的宿舍号码,重新输入: "); } while(scanf("%s",p1->tel)&&checknum(p1->tel)==0) { printf("输入错误的手机号码,重新输入: "); } printf(" "); } p2->next=NULL;//最后p1开辟的新节点丢弃了,让p2的next指向空,形成表尾结束链表。 录入结束 system("cls"); fflush(stdin); return(head); } void score(struct student *head)//拿到链表,录入成绩 { system("cls"); fflush(stdin); printf("*****************************************************成绩录入*********************************************************** "); printf("依次键入语文、数学、英语、体育、专业成绩,用一个空格隔开各数据,每一条输入完成后按回车键进行下一条输入。 "); printf(" 【录完分数后自动退出】 "); printf("例如: 10 20 30 40 50 在此输入: "); int Aver;//平均分 struct student *p; for(p=head;p!=NULL;p=p->next)//遍历链表 { printf(" 现在录入%s(%s)的成绩 ",p->name,p->num); while(scanf("%s",p->CHN)&&checkscore(p->CHN)==0) { printf("输入错误的语文分数,重新输入: "); } while(scanf("%s",p->MATH)&&checkscore(p->MATH)==0) { printf("输入错误的数学分数,重新输入: "); } while(scanf("%s",p->ENG)&&checkscore(p->ENG)==0) { printf("输入错误的英语分数,重新输入: "); } while(scanf("%s",p->PE)&&checkscore(p->PE)==0) { printf("输入错误的体育分数,重新输入: "); } while(scanf("%s",p->PRO)&&checkscore(p->PRO)==0) { printf("输入错误的专业分数,重新输入: "); } Aver=(transformint(p->CHN)+transformint(p->MATH)+transformint(p->ENG)+transformint(p->PE)+transformint(p->PRO))/5; itoa(Aver,p->average_score,10);//Aver十进制形式转化为字符串存储在链表的average_score平均分里 printf("%s的成绩录入完了 ",p->name); } system("cls"); fflush(stdin); } void findinformation(struct student *head)//学生信息查询 { system("cls"); fflush(stdin); char choose1[20],choose2[20];//两个选择的地方,choose1选择学号/姓名 or 宿舍号 ,choose2在选择了学号/姓名时选择 学号 or 姓名 char num[20]={'1'};//用户即将输入的学号 char name[20];//用户即将输入的姓名 char room[20]={'1'};//用户即将输入的宿舍号 struct student *p; p=head; int flag=0; printf("*****************************************************信息查询*********************************************************** "); printf(" 选择查找方式,学号/姓名查找(输入1),宿舍号(输入2) 请在此输入:"); choosestation1://第一次选择的点 fflush(stdin); while(scanf("%s",choose1)&&checknum(choose1)==0) { printf("输入无效,重新输入: "); } if(transformint(choose1)==1) { printf("通过学号(输入1),姓名(输入2):"); choosestation2://第二次选择的点 fflush(stdin); while(scanf("%s",choose2)&&checknum(choose2)==0) { printf("输入无效,重新输入: "); } if(transformint(choose2)==1) { while(transformint(num)!=0) { printf(" 输入学号(输入0并回车结束):"); while(scanf("%s",num)&&checknum(num)==0) { printf("输入错误的学号,重新输入: "); } for(p=head;p!=NULL;p=p->next) { if(transformint(p->num)==transformint(num)) { printf("学号:%s 姓名:%s 性别:%s 宿舍号码:%s 电话号码:%s ",p->num,p->name,p->sex,p->room,p->tel); flag=1; break; } } if(flag==0&&transformint(num)!=0) { printf("未找到此学生信息 "); } } }else if(transformint(choose2)==2) { while(name[0]!='#') { printf(" 输入姓名(输入#并回车结束):"); scanf("%s",name); for(p=head;p!=NULL;p=p->next)//遍历链表 { if(strcmp(p->name,name)==0)//比较两字符串 { printf("学号:%s 姓名:%s 性别:%s 宿舍号码:%s 电话号码:%s ",p->num,p->name,p->sex,p->room,p->tel); flag=1; break; } } if(flag==0&&name[0]!='#') { printf("未找到此学生信息! "); } } }else { printf("输入了错误的第二次选择数字!重新输入: "); goto choosestation2;//返回上面第二次选择的点 } }else if(transformint(choose1)==2) { while(transformint(room)!=0) { printf(" 输入宿舍号(输入0并回车结束):"); while(scanf("%s",room)&&checknum(room)==0) { printf("输入错误的宿舍号码,重新输入: "); } for(p=head;p!=NULL;p=p->next) { if(p->room==room) { printf("学号:%s 姓名:%s 性别:%s 宿舍号码:%s 电话号码:%s ",p->num,p->name,p->sex,p->room,p->tel); flag=1; break; } } if(flag==0&&transformint(room)!=0) { printf("未找到此学生信息! "); } } }else { printf("输入了错误的第一次选择数字!重新输入: "); goto choosestation1;//返回最上面第一次选择的点 } system("cls"); fflush(stdin); } void findscore(struct student *head)//成绩查询 { system("cls"); fflush(stdin); char num[20]={'1'};//初始化用户即将输入的学号 struct student *p; int flag=0;//学号是否找到的标志,1找到0没找到 p=head; printf("*****************************************************成绩查询*********************************************************** "); printf("因为有重名的可能,暂时只能通过学号进行查询。请输入学号并回车进行查询! "); printf(" 【退出请输入'0'并回车】 "); while(transformint(num)!=0) { printf(" 输入学号:"); while(scanf("%s",num)&&checknum(num)==0) { printf("输入错误的学号,重新输入: "); } for(p=head;p!=NULL;p=p->next) { if(transformint(p->num)==transformint(num)) { printf("学号:%s 姓名:%s 语文:%s 数学:%s 英语:%s 体育:%s 专业:%s ",p->num,p->name,p->CHN,p->MATH,p->ENG,p->PE,p->PRO); flag=1; break; } } if(flag==0) { printf("学号未找到! "); } } system("cls"); fflush(stdin); } struct student *del(struct student *head)//删除信息函数 { system("cls"); fflush(stdin); char num[20]={'1'};//用户即将输入的学号 struct student *p1,*p2; printf("*****************************************************信息删除*********************************************************** "); if(head == NULL) { system("cls"); fflush(stdin); return(head); } printf(" ***************************************输入学号进行删除学生信息(输入0结束)********************************************** "); do{ printf(" 请输入学号:"); while(scanf("%s",num)&&checknum(num)==0) { printf("输入错误的学号,重新输入: "); } if(transformint(num)==0) { break; } p1=p2=head; while(transformint(num)!=transformint(p1->num)&&p1->next!=NULL) { p2=p1; p1=p1->next; } if(transformint(num)==transformint(p1->num))//找到数字 { if(p1==head)//如果是要删开头的节点,直接改变表头指向第二个节点,让第二个节点成为新的表头,原来的头用free释放掉 { head=p1->next; free(p1); }else//如果删后面的节点,要把p2连到p1所在节点后面的一个节点,将p1所在节点free释放掉 { p2->next=p1->next; free(p1); } printf("已删除学号为%s的信息",num); n=n-1; }else { printf("没有找到学号为%s的学生 ",num); } }while(transformint(num)!=0); system("cls"); fflush(stdin); return(head); } struct student *insert(struct student *head)//插入信息函数 { system("cls"); fflush(stdin); printf("*****************************************************信息追加*********************************************************** "); printf(" 【加入一组信息后自动退出】 "); printf("请按照 学号 姓名 性别 宿舍号码 电话号码 语文 数学 英语 体育 专业 顺序输入 "); printf("样例: 542013460658 李四 男 1206 10086 10 20 30 40 50 "); int Aver; struct student *stud=(struct student*)malloc(LEN);//开辟一个单元,这一块存我们追加的信息,后面的操作把这一块连接到链表的表头 stud->next=NULL; stud->next=head; head=stud; while(scanf("%s",stud->num)&&checknum(stud->num)==0) { printf("输入错误的学号,重新输入: "); } while(scanf("%s",stud->name)&&IncludeChinese(stud->name)==0) { printf("输入错误的名字,重新输入: "); } while(scanf("%s",stud->sex)&&IncludeChinese(stud->sex)==0) { printf("输入错误的性别,重新输入: "); } while(scanf("%s",stud->room)&&checknum(stud->room)==0) { printf("输入错误的宿舍号码,重新输入: "); } while(scanf("%s",stud->tel)&&checknum(stud->tel)==0) { printf("输入错误的电话号码,重新输入: "); } while(scanf("%s",stud->CHN)&&checkscore(stud->CHN)==0) { printf("输入错误的语文分数,重新输入: "); } while(scanf("%s",stud->MATH)&&checkscore(stud->MATH)==0) { printf("输入错误的数学分数,重新输入: "); } while(scanf("%s",stud->ENG)&&checkscore(stud->ENG)==0) { printf("输入错误的英语分数,重新输入: "); } while(scanf("%s",stud->PE)&&checkscore(stud->PE)==0) { printf("输入错误的体育分数,重新输入: "); } while(scanf("%s",stud->PRO)&&checkscore(stud->PRO)==0) { printf("输入错误的专业分数,重新输入: "); } Aver=(transformint(stud->CHN)+transformint(stud->MATH)+transformint(stud->ENG)+transformint(stud->PE)+transformint(stud->PRO))/5;//计算平均分 itoa(Aver,stud->average_score,10); n=n+1; //节点+1 system("cls"); fflush(stdin); return(head); } void update(struct student *head)//修改分数 { system("cls"); fflush(stdin); int Aver; struct student *p1,*p2; char num[20]={'1'};//用户即将输入的学号 char choose[20]; printf("*****************************************************分数修改*********************************************************** "); if(head == NULL)//没有录信息 空表直接返回 { system("cls"); fflush(stdin); return; } printf(" ***************************************输入学号进行修改学生分数(输入0结束)********************************************** "); do{ printf(" 请输入学号:"); while(scanf("%s",num)&&checknum(num)==0) { printf("输入错误的学号,重新输入: "); } if(transformint(num)==0) { break; } p1=p2=head; while(transformint(p1->num)!=transformint(num)&&p1->next!=NULL)//没找到,往后走 { p2=p1; p1=p1->next; } if(transformint(p1->num)==transformint(num))//找到了,开始选修改的科目 { printf("修改语文请输入1,数学输入2,英语3,体育4,专业5 "); printf("请输入修改科目对应的数字:"); while(scanf("%s",choose)&&checknum(choose)==0||transformint(choose)<1||transformint(choose)>5) { printf("输入无效的编号,重新输入: "); } printf("请输入修改后的分数:"); switch(transformint(choose)) { case 1: while(scanf("%s",p1->CHN)&&checknum(p1->CHN)==0) { printf("输入错误的语文分数,重新输入: "); } break; case 2: while(scanf("%s",p1->MATH)&&checknum(p1->MATH)==0) { printf("输入错误的数学分数,重新输入: "); } break; case 3: while(scanf("%s",p1->ENG)&&checknum(p1->ENG)==0) { printf("输入错误的英语分数,重新输入: "); } break; case 4: while(scanf("%s",p1->PE)&&checknum(p1->PE)==0) { printf("输入错误的体育分数,重新输入: "); } break; case 5: while(scanf("%s",p1->PRO)&&checknum(p1->PRO)==0) { printf("输入错误的专业分数,重新输入: "); } break; } Aver=(transformint(p1->CHN)+transformint(p1->MATH)+transformint(p1->ENG)+transformint(p1->PE)+transformint(p1->PRO))/5; itoa(Aver,p1->average_score,10);//平均分转换字符串形式 }else { printf("没有找到学号为%s的学生 ",num); } }while(transformint(num)!=0); system("cls"); fflush(stdin); } void Oscore(struct student*head)//排序输出 { system("cls"); fflush(stdin); printf("*****************************************************查看排名*********************************************************** "); int ranking=0; struct student *p=NULL,*p1=NULL; for(p=head;p!=NULL;p=p->next) { if(checkscore(p->average_score)==0) { printf("有同学只录取了信息,没有录成绩。所以无法公布排名 "); system("pause"); system("cls"); fflush(stdin); return; } } for(p=head;p!=NULL;p=p->next) { for(p1=p->next;p1!=NULL;p1=p1->next) { if(transformint(p->average_score) average_score)) { swap(p,p1); } } } printf("学号 姓名 平均分 名次 语文 数学 英语 体育 专业 "); for(p=head;p!=NULL;p=p->next) { ranking+=1; printf("%s %s %s %d %s %s %s %s %s ",p->num,p->name,p->average_score,ranking,p->CHN,p->MATH,p->ENG,p->PE,p->PRO); } printf(" "); system("pause"); system("cls"); fflush(stdin); } void swap(struct student*p1,struct student*p2)//交换数据(辅助函数) { char tempCHN[20]; char tempMATH[20]; char tempENG[20]; char tempPE[20]; char tempPRO[20]; char tempaverage[20]; char tempname[20]; char tempnum[20]; strcpy(tempnum,p1->num);/// strcpy(p1->num,p2->num); strcpy(p2->num,tempnum); strcpy(tempname,p1->name);// strcpy(p1->name,p2->name); strcpy(p2->name,tempname); strcpy(tempCHN,p1->CHN);/// strcpy(p1->CHN,p2->CHN); strcpy(p2->CHN,tempCHN); strcpy(tempMATH,p1->MATH);/// strcpy(p1->MATH,p2->MATH); strcpy(p2->MATH,tempMATH); strcpy(tempENG,p1->ENG);/// strcpy(p1->ENG,p2->ENG); strcpy(p2->ENG,tempENG); strcpy(tempPE,p1->PE);/// strcpy(p1->PE,p2->PE); strcpy(p2->PE,tempPE); strcpy(tempPRO,p1->PRO);/// strcpy(p1->PRO,p2->PRO); strcpy(p2->PRO,tempPRO); strcpy(tempaverage,p1->average_score);/// strcpy(p1->average_score,p2->average_score); strcpy(p2->average_score,tempaverage); } void fenduan(struct student*head)//分段输出 { system("cls"); fflush(stdin); printf("*****************************************************成绩分段*********************************************************** "); struct student *p; for(p=head;p!=NULL;p=p->next) { if(checkscore(p->average_score)==0) { printf("有同学只录取了信息,没有录成绩。所以无法公布分段 "); system("pause"); system("cls"); fflush(stdin); return; } } printf("********************************************************A*************************************************************** "); printf("学号 姓名 平均分 语文 数学 英语 体育 专业 "); for(p=head;p!=NULL;p=p->next) { if(transformint(p->average_score)>=80) { printf("%s %s %s %s %s %s %s %s ",p->num,p->name,p->average_score,p->CHN,p->MATH,p->ENG,p->PE,p->PRO); } } printf("********************************************************B*************************************************************** "); printf("学号 姓名 平均分 语文 数学 英语 体育 专业 "); for(p=head;p!=NULL;p=p->next) { if(transformint(p->average_score)<80&&transformint(p->average_score)>=60) { printf("%s %s %s %s %s %s %s %s ",p->num,p->name,p->average_score,p->CHN,p->MATH,p->ENG,p->PE,p->PRO); } } printf("********************************************************C*************************************************************** "); printf("学号 姓名 平均分 语文 数学 英语 体育 专业 "); for(p=head;p!=NULL;p=p->next) { if(transformint(p->average_score)<60) { printf("%s %s %s %s %s %s %s %s ",p->num,p->name,p->average_score,p->CHN,p->MATH,p->ENG,p->PE,p->PRO); } } printf(" "); system("pause"); system("cls"); fflush(stdin); } void save(struct student *head)//文件保存 { system("cls"); fflush(stdin); FILE *fp; struct student *p; fp=fopen("stu.db","wb"); for(p=head;p!=NULL;p=p->next) { fwrite(p,LEN,1,fp); } fclose(fp); printf("保存完毕 "); system("pause"); system("cls"); fflush(stdin); } void export1()//文件输出 { system("cls"); fflush(stdin); FILE *fp; struct student *t; t=(struct student *)malloc(LEN); if((fp=fopen("stu.db","r"))==NULL){ printf("未找到文件 "); } else{ printf("学号 姓名 平均分 语文 数学 英语 体育 专业 "); int w; fseek(fp,0,2); w=ftell(fp); fseek(fp,0,0); while(w!=ftell(fp)){ fread(t,LEN,1,fp); printf("%s %s %s %s %s %s %s %s ",t->num,t->name,t->average_score,t->CHN,t->MATH,t->ENG,t->PE,t->PRO); } fclose(fp); } system("pause"); system("cls"); fflush(stdin); } struct student *import()//文件导入 { system("cls"); fflush(stdin); FILE *fp; if((fp=fopen("stu.db","r"))==NULL){ printf("未找到文件 "); } else{ struct student *p1,*p2,*head; p1=p2=(struct student *)malloc(LEN); fread(p1,LEN,1,fp); while(!feof(fp)) {//end of file n+=1; if(n==1){ head=p1; } else{ p2->next=p1; } p2=p1; p1=(struct student *)malloc(LEN); fread(p1,LEN,1,fp); } p2->next=NULL; fclose(fp); printf("文件导入成功 "); system("pause"); system("cls"); fflush(stdin); return head; } system("cls"); fflush(stdin); return NULL; } int checknum(char ch[])//检查纯数字的数据里是否混入了非数字的非法输入; { int i,flag=1; for(i=0;i '9') { flag=0; break; } } return flag; } int checkscore(char ch[])//检查0-99分数 { int i,flag=1; if(strlen(ch)>=3) { return 0; } for(i=0;i '9') { flag=0; break; } } return flag; } int IncludeChinese(char *str)//是否包含中文 { char c; while(1) { c=*str++; if (c==0) break; //如果到字符串尾则说明该字符串没有中文字符 if (c&0x80) //如果字符高位为1且下一字符高位也是1则有中文字符 if (*str & 0x80) return 1; } return 0; } int transformint(char ch[])//纯数字整数(字符串转向int类型) { int i=0,sum=0; for(i=0;i 审核编辑:汤梓红
评论
查看更多