文章目录

  • 一、系统概述
  • 二、数据类型
  • 三、自定义函数说明
  • 四、运行界面
  • 五、源代码

源代码请直接跳到最后

引言:最近写了C语言的大作业,感觉做得还行,记录一下,给后人一些参考,给自己留更深印象方便后续改进!

不知道发了这篇博客会不会认为我抄袭…害怕.jpg

一、系统概述

使用单向链表和文件作为基本数据结构,设计一个学生成绩管理程序,管理某学校学生成绩。
[1]插入数据
[2]修改对应数据项的数据
[3]删除对应学号的信息
[4]查找某学号的信息
[5]查找不及格学生
[6]对学生成绩进行排名
[7]统计各个等级的学生人数
[8]输出所有学生信息
[9]分页显示学生信息

二、数据类型

//枚举
enum sex{women,man};
struct StuLink{int  xh;                   //学号char xm[20];               //姓名 enum sex  xb;              //性别 int  cj;                   //成绩,范围[0,100]    前四个为输入项 char dj;                   //等级int  mc;                   //名次struct StuLink *next;      //下一项
};
char sex[][3]={"女","男"};     //用于输出“男女”中文字符
int size=sizeof(struct StuLink);  //节点字节大小
  1. 注意姓名是xm[20],是字符串;而等级是cj,单个字符;这会影响到赋值问题
  2. 其中姓名、性别、成绩是输入项,名字、等级、名次由程序计算得出

三、自定义函数说明

1. main 函数

函数首部:void main

参数列表:
[1] menu1:用于接收一级菜单选择
[2] menu2:用于接收一级菜单选择
[3] i:用于 for 循环迭代变量
[4]n:用于接收“插入数据”功能的学生个数
[5] dj_add[5]:用于储存各等级人数
[6] head:用于储存头节点的地址
[7]pw:用于储存尾节点的地址

返回值:无

实现功能:选择对应功能并实现

算法描述:

void main(){//  声明变量int menu1,menu2;        //menu1:一级菜单 menu2:二级菜单  int i=0,n,dj_add[5]={0,0,0,0,0};struct StuLink *head=NULL,*pw;   //*head:学生信息链表头指针 pw:尾节点 //  声明函数
// 从数据文件中逐行读取学生信息生成学生链表,返回头指针 struct StuLink *ReadFromFile();
//  先将学生链表按学号升序排序,再将学生链表中的数据逐行保存到数据文件void SaveToFile(struct StuLink *head);
//  SortLink函数:按指定数据项的顺序【1:学号(升序)】或者【2:成绩(降序)】对学生链表进行排序 struct StuLink *SortLink(struct StuLink *head,int i);
//  InsertNode函数:在链表尾插入一个新结点。新结点的学号是链表中最大学号加1,姓名和成绩从键盘输入
//  (注意:成绩必须在[0,100]区间的整数),根据成绩计算等级。
//  注意:插入结点会导致链表中各结点名次的变化。struct StuLink *InsertNode(struct StuLink *pw);
//  EditNode函数:修改链表中指定学号的结点(学号不能修改,成绩必须在[0,100]区间的整数)
//  注意:当修改成绩时会导致等级和名次的变化void EditNode(struct StuLink *head);
//DeleteNode函数:删除链表中指定学号的结点。注意:删除结点会导致链表中各结点名次的变化struct StuLink *DeleteNode(struct StuLink *head);
//  QueryNode函数:查询链表中指定学号的结点,并显示查询结果。
void QueryNode(struct StuLink *head);
//  QueryLink函数:查询链表中不及格的所有结点,并显示查询结果。
void QueryLink(struct StuLink *head);
//RankLink函数:计算链表中每个结点的名次。名次规则:按成绩降序排名,从第1名开始依次排名,
//若出现并列名次,则名次需要叠加。例如,若出现5个并列第1名,则没有第2名,下一个名次是第6名,依此类推。
void RankLink(struct StuLink *head);
//AnalysisLink函数:统计并返回各等级人数。等级标准:
//A:90及以上        B:80及以上      C:70及以上      D:60及以上      E:60以下
void AnalysisLink(struct StuLink *head,int *dj_add);
//OutputLink_1函数:按指定数据项的顺序【1:学号(升序)】或者【2:成绩(降序)】输出学生成绩表、各等级人数。
//学生成绩表每行输出一个学生信息(依次为学号、姓名、性别、成绩、等级和名次,各项间以1个空格隔开),
//各等级人数分行输出。
void  OutputLink_1(struct StuLink *head,int i);
//OutputLink_2函数:分页显示全部学生的信息。
//分页功能:每页显示10个学生信息,有上一页、下一页、首页和最后一页的翻页功能。
void  OutputLink_2(struct StuLink *head,int i);//   执行语句head=ReadFromFile();     //读取文件到链表,获取头指针 // 菜单while(1){system("cls");                  //清控制台,Windows printf("========================================\n");//40个=printf("=                                      =\n");printf("=           学生成绩管理程序           =\n");printf("=                              by:xxx =\n"); printf("========================================\n");printf("=                                      =\n");printf("=        1-数据维护  2-数据查询        =\n");printf("=        3-统计分析  4-报表输出        =\n");printf("=                0-退出                =\n");printf("=                                      =\n");printf("========================================\n");
//      printf("\n");printf("请选择:");scanf("%d",&menu1); switch(menu1){                 //一级菜单 case 1:while(1){                      //循环输出二级菜单 system("cls");printf("\n");printf("========================================\n");printf("=                                      =\n");printf("=        1-数据插入  2-数据修改        =\n");printf("=        3-数据删除  0-返回上级        =\n");printf("=                                      =\n");printf("========================================\n");printf("请选择:");scanf("%d",&menu2); switch(menu2){      //二级菜单 case 1:printf("请输入要插入的学生个数(n>0): "); scanf("%d",&n);while(n<=0){printf("!!!请输入正确的学生个数!!!: ");scanf("%d",&n);}pw=head;if(pw){while(pw->next)   //获取尾部节点 pw=pw->next;}for(i=0;i<n;i++){pw=InsertNode(pw);if(head==NULL) head=pw;}//   计算名次RankLink(head);
//                          SaveToFile(head);       break;case 2:EditNode(head);//  计算名次RankLink(head);
//                          SaveToFile(head);break;case 3:head=DeleteNode(head);// 计算名次RankLink(head);
//                          SaveToFile(head);   break;case 0:break;}if(menu2==0) break;}break;case 2:while(1){                      //循环输出二级菜单 system("cls");printf("\n");printf("========================================\n");printf("=                                      =\n");printf("=1-学号查询 2-不及格学生查询 0-返回上级=\n");printf("=                                      =\n");printf("========================================\n");printf("请选择:");scanf("%d",&menu2); switch(menu2){      //二级菜单 case 1:QueryNode(head);printf("\n"); system("pause");break;case 2:QueryLink(head); printf("\n"); system("pause");break;case 0:break;}if(menu2==0) break;}break;case 3:while(1){                      //循环输出二级菜单 system("cls");printf("\n");printf("========================================\n");printf("=                                      =\n");printf("=    1-成绩名次计算  2-成绩频次分析    =\n");printf("=              0-返回上级              =\n");printf("=                                      =\n");printf("========================================\n");printf("请选择:");scanf("%d",&menu2); switch(menu2){      //二级菜单 case 1:RankLink(head);break;case 2:AnalysisLink(head,dj_add);printf("'A'有%d人;'B'有%d人,'C'有%d人,'D'有%d人,'E'有%d人,共有%d人\n",dj_add[0],dj_add[1],dj_add[2],dj_add[3],dj_add[4],dj_add[0]+dj_add[1]+dj_add[2]+dj_add[3]+dj_add[4]); printf("\n"); system("pause"); break;case 0:break;}if(menu2==0) break;}break;case 4:while(1){                      //循环输出二级菜单 system("cls");printf("\n");printf("========================================\n");printf("=                                      =\n");printf("=1-排序显示学生信息  2-分页显示学生信息=\n");printf("=              0-返回上级              =\n");printf("=                                      =\n");printf("========================================\n");printf("请选择:");scanf("%d",&menu2); switch(menu2){      //二级菜单 case 1:printf("请选择按【1:学号(升序)】或者【2:成绩(降序)】输出学生成绩表:");scanf("%d",&i);while((i!=1)&&(i!=2)){printf("!!!请选择正确选项!!!1 or 2 : ");scanf("%d",&i);}OutputLink_1(head,i);printf("\n"); system("pause"); break;case 2:printf("请选择按【1:学号(升序)】或者【2:成绩(降序)】输出学生成绩表:");scanf("%d",&i);while((i!=1)&&(i!=2)){printf("!!!请选择正确选项!!!1 or 2 : ");scanf("%d",&i);}OutputLink_2(head,i);break;case 0:break;}if(menu2==0) break;}break;case 0:printf("========================================\n");printf("=                                      =\n");printf("=        你已经退出学生管理系统        =\n");printf("=                                      =\n");printf("========================================\n");return;       //退出main函数 }} }

2. ReadFromFile 函数

函数首部:struct StuLink *ReadFromFile()

参数列表:
[1]fp:用于储存储存在缓冲区的文件地址
[2]p1:用于储存开辟的新节点的地址
[3]p2:用于储存尾节点的地址
[4]head:用于储存首节点的地址
[5]ch:用于接收文件第一个字符

返回值:head 的地址

实现功能:
1.写打开文件
2.2.读取文件第一个字符,若是 EOF 文件终止符,则返回 head 的指针,函数结束;否则将 fp 的地址重置为文件开头
3.3.循环:若 fp 指针不为空,则开辟新节点,并且接入链表的尾节点(根据情况),读取 文件第一行信息并且赋值到 p1 指向的节点中
4.4.写关闭文件,返回 head 的地址

算法描述:

struct StuLink *ReadFromFile(){FILE *fp;                           //指向student.dat文件 struct StuLink *p1,*p2,*head=NULL;  //head:头节点  p1:开辟新节点  p2:尾节点 char ch;if((fp=fopen("student.dat","r"))==NULL){   //读开student.dat printf("打开student.dat失败\n");exit(0); } ch=fgetc(fp);                               //读取文件第一个字符if(ch==EOF){                                //EOF文件终止符printf("文件为空\n");return head;   }else{rewind(fp);                            // 将fp的地址重置为文件开头}while(!feof(fp)){if((p1=(struct StuLink *)malloc(size))==NULL) {printf("不能成功分配储存块");exit(0);}p1->next=NULL;if(head==NULL)  head=p1;        //首节点 else p2->next=p1;     //非首节点,表尾插入新节点 p2=p1;                    // p2指向新的表尾结点 fscanf(fp,"%d %s %d %d %s %d\n",&p1->xh,p1->xm,&p1->xb,&p1->cj,&p1->dj,&p1->mc);
//      读取\n是防止fp以为文件未完 printf("%-5d%-10s%-5d%-5d%-5c%-5d\n",p1->xh,p1->xm,p1->xb,p1->cj,p1->dj,p1->mc);}fclose(fp);                                 //关闭student.datreturn head;
}

3. SortLink 函数

函数首部:struct StuLink *SortLink(struct StuLink *head,int i)

参数列表:
[1]head:储存首节点的地址
[2]i:用于储存排序方式的选项
[3]xh:用于储存学号
[4]xb:用于储存性别
[5]cj:用于储存成绩
[6]mc:用于储存名次
[7]xm:用于储存姓名
[8]dj:用于储存等级
[9]p1:用于表示被比较节点的地址
[10]p2:用于表示比较节点的地址
[11]p3:用于表示中间节点的地址

返回值:head 的地址

实现功能:

  1. 判断 head 是否为空,为空则返回 head 并且结束函数
  2. 进行排序,快速排序,交换连个节点的数据项,而不是改变链表的节点信息
  3. 返回 head,结束函数

算法描述:

struct StuLink *SortLink(struct StuLink *head,int i){if(head==NULL)return head;
//      使用交换数据的形式交换两个节点 int xh,xb,cj,mc;char xm[20],dj;
//      p1:被比较节点  p2:比较节点  p3:快速排序储存节点 struct StuLink *p1=head,*p2=head->next,*p3=p1;switch(i){case 1:
//              快速排序while(p1->next){p2=p1->next;p3=p1;while(p2){if(p3->xh>p2->xh) p3=p2;p2=p2->next;}if(p3->xh<p1->xh){xh=p3->xh;  xb=p3->xb;cj=p3->cj;  mc=p3->mc;strcpy(xm,p3->xm);  dj=p3->dj;p3->xh=p1->xh;  p3->xb=p1->xb;p3->cj=p1->cj;  p3->mc=p1->mc;strcpy(p3->xm,p1->xm);  p3->dj=p1->dj;p1->xh=xh;  p1->xb=xb;p1->cj=cj;  p1->mc=mc;strcpy(p1->xm,xm);  p1->dj=dj;} p1=p1->next;} break;case 2:
//              快速排序while(p1->next){p2=p1->next;p3=p1;while(p2){if(p3->cj<p2->cj) p3=p2;p2=p2->next;}if(p3->cj>p1->cj){xh=p3->xh;  xb=p3->xb;cj=p3->cj;  mc=p3->mc;strcpy(xm,p3->xm);  dj=p3->dj;p3->xh=p1->xh;  p3->xb=p1->xb;p3->cj=p1->cj;  p3->mc=p1->mc;strcpy(p3->xm,p1->xm);  p3->dj=p1->dj;p1->xh=xh;  p1->xb=xb;p1->cj=cj;  p1->mc=mc;strcpy(p1->xm,xm);  p1->dj=dj;} p1=p1->next;} break;} return head;}

4. SaveToFile 函数

函数首部:void SaveToFile(struct StuLink *head)

参数列表:
[1]head:用于表示首节点的地址
[2]fp:用于表示缓冲区文件的地址
[3]i:用于储存排序方式

返回值:无

实现功能:写开文件,循环将链表中的信息储存到文件中

算法描述:

 void SaveToFile(struct StuLink *head){FILE *fp;int i=1;head=SortLink(head,i);struct StuLink *p=head;if((fp=fopen("student.dat","w"))==NULL){printf("写开文件失败!");exit(0);}while(p){//          写入文件 fprintf(fp,"%d %s %d %d %c %d\n",p->xh,p->xm,p->xb,p->cj,p->dj,p->mc);p=p->next;}fclose(fp); }

5. InsertNode 函数

函数首部:struct StuLink *InsertNode

参数列表:
[1]pw:用于表示链表尾节点的地址
[2]p1:用于表示新节点的地址
[3]xm:用于表示姓名字符串的地址

返回值:pw 的地址

实现功能:开辟一个新节点,用 p1 指向新节点,并向其赋值,同时检查性别和成绩的正确性, 根据成绩计算等级,再将 p1 接在 pw 后面

算法描述

struct StuLink *InsertNode(struct StuLink *pw){struct StuLink *p1;    //pw:原链表尾节点     p1:开辟新节点 if((p1=(struct StuLink *)malloc(size))==NULL) {printf("不能成功分配储存块\n");exit(0);}p1->next=NULL;if(pw)p1->xh=pw->xh+1;else p1->xh=1;char xm[20];printf("请依次输入姓名、性别(男1女0)、成绩[0,100]:  ");scanf("%s%d%d",xm,&p1->xb,&p1->cj);while(p1->xb!=0&&p1->xb!=1){printf("! ! ! 性别只能是1或0,请重新输入性别1:男    0:女   ");scanf("%d",&p1->xb); }while(p1->cj<0 || p1->cj>100){printf("! ! ! 成绩范围是0~100,请重新输入成绩   ");scanf("%d",&p1->cj); }strcpy(p1->xm,xm);//  p1->mc=1;  // 名次暂时命名为1 if(p1->cj>=90) p1->dj='A';else if(p1->cj>=80)  p1->dj='B';else if(p1->cj>=70)  p1->dj='C';else if(p1->cj>=60)  p1->dj='D';else p1->dj='E';if(pw==NULL)   pw=p1;else{pw->next=p1;    pw=pw->next;}return pw;
}

6. EditNode函数

函数首部:void EditNode(struct StuLink *head)

参数列表:
[1]head:用于表示首节点的地址
[2]p1:用于表示循环寻找对应学号地址
[3]xm:用于表示姓名字符串
[4]n:用于表示要修改的学号
[5]re:用于表示要修改的数据项

返回值:无 实现功能:先判断链表是否为空,为空则退出函数。输入一个学号,判断是否存在,不存在则退 出函数;存在则输出对应学生信息,选择要修改的数据项进行修改

返回值:无

算法描述:

void EditNode(struct StuLink *head){if(head==NULL){printf("学生数据为空!\n");printf("\n"); system("pause"); return;}struct StuLink *p1=head;char xm[20];int n,re;printf("请输入你要修改的学生信息的学号:");scanf("%d",&n) ;while(p1){if(p1->xh==n){break;}else{p1=p1->next;}}if(p1){printf("你要修改的学生信息为:\n");printf("学号  姓名      性别  成绩  等级  名次   ##男1女0##\n");printf("%-6d%-10s%-6d%-6d%-6c%-6d\n",p1->xh,p1->xm,p1->xb,p1->cj,p1->dj,p1->mc);} else{printf("你输入的学号有误!\n");printf("\n"); system("pause"); return;} printf("请选择要修改的数据项:0-不修改 1-姓名 2-性别 3-成绩  "); scanf("%d",&re);while(re<0||re>3){printf("输入有误!重新输入: ");scanf("%d",&re);}switch(re){case 0:break;case 1:printf("请输出新的姓名:");scanf("%s",xm);strcpy(p1->xm,xm);break;case 2:printf("请输入新的性别:");scanf("%d",&p1->xb);while(p1->xb!=0&&p1->xb!=1){printf("! ! ! 性别只能是1或0,请重新输入性别1:男    0:女   ");scanf("%d",&p1->xb); }break;case 3:printf("请输入新的成绩:");scanf("%d",&p1->cj);while(p1->cj<0 || p1->cj>100){printf("! ! ! 成绩范围是0~100,请重新输入成绩   ");scanf("%d",&p1->cj); }if(p1->cj>=90) p1->dj='A';else if(p1->cj>=80)  p1->dj='B';else if(p1->cj>=70)  p1->dj='C';else if(p1->cj>=60)  p1->dj='D';else p1->dj='E';break;   }
}

**7. DeleteNode 函数 **

函数首部:struct StuLink *DeleteNode(struct StuLink *head)

参数列表:
[1]head:用于表示首节点的地址
[2]p1:用于表示循环查找对应节点的地址
[3]p2:用于表示 p1 指向的节点的前驱节点的地址
[4]del_xh:用于表示被删除学生的学号

返回值:head 的地址

算法描述:

struct StuLink *DeleteNode(struct StuLink *head){if(head==NULL){printf("学生数据为空!\n");printf("\n"); system("pause");    return head;}struct StuLink *p1=head,*p2;int del_xh;printf("请输入要删除的学号:");scanf("%d",&del_xh); while((p1->xh!=del_xh)&&(p1->next!=NULL)){p2=p1;p1=p1->next;} if(p1->xh==del_xh){   //找到 if(head==p1) head=head->next;   //首节点 else p2->next=p1->next;         //非首节点 free(p1); printf("删除成功!\n");}else printf("未找到此学号对应节点!\n");printf("\n"); system("pause"); return head;
}

8. QueryNode 函数

函数首部:void QueryNode(struct StuLink *head)

参数列表:
[1]head:用于表示首节点的地址
[2]query_xh:用于表示查询的学号
[3]p1:用于表示循环查找对应节点的地址
[4]p2:用于表示 p1 指向的节点的前驱节点的地址

返回值:无

实现功能:先判断链表是否为空,为空则退出函数。接收要查询的学号,循环寻找,找到则输出学学 生信息;否则输出未找到

算法描述:

void QueryNode(struct StuLink *head){if(head==NULL){printf("学生数据为空!\n");printf("\n"); system("pause");    return;}int query_xh;struct StuLink *p1=head,*p2;printf("请输入要查询的学生学号:");scanf("%d",&query_xh); while((p1->xh!=query_xh)&&(p1->next!=NULL)){p2=p1;p1=p1->next;} if(p1->xh==query_xh){           //找到 printf("查找结果为:\n"); printf("学号:%-5d姓名:%-10s成绩:%-5d等级:%-5c名次:%-5d",p1->xh,p1->xm,p1->cj,p1->dj,p1->mc);if(p1->xb==1) printf("性别:男\n");else printf("性别:女\n"); }else printf("未找到该学号对应学生!\n");
}

9. QueryLink 函数

函数首部:void QueryLink(struct StuLink *head)

参数列表:
[1]head:用于表示首节点的地址
[2]p1:用于表示循环链表各节点的地址
[3]n:用于表示循环次数

返回值:无

实现功能:先判断链表是否为空,为空则退出函数。循环查找不及格学习,符合则输出,不符合则下 一个。若一个不及格的都没有,则输出没有不及格学生

算法描述:

void QueryLink(struct StuLink *head){if(head==NULL){printf("学生数据为空!\n");printf("\n"); system("pause");    return;}struct StuLink *p1=head;int n=0;while(p1){if(p1->cj<60){n++; if(n==1) printf("未及格学生信息为:\n"); printf("学号:%-5d姓名:%-10s成绩:%-5d等级:%-5c名次:%-5d",p1->xh,p1->xm,p1->cj,p1->dj,p1->mc);if(p1->xb==1) printf("性别:男\n");else printf("性别:女\n"); }p1=p1->next;}if(n==0) printf("没有不及格学生!\n");
}

10. RankLink 函数

函数首部:void RankLink(struct StuLink *head)

参数列表:
[1]head:用于表示首节点的地址
[2]i:用于表示排序的升降序
[3]p1:用于表示循环链表中节点的地址
[4]p2:用于表示 p1 指向的节点的前驱节点的地址
[5]n:用于表示循环次数

返回值:无

实现功能:先判断链表是否为空,为空则退出函数。学生按成绩降序排序,再计算链表中每个结 点的名次,最后保存(学号升序)到文件中。

算法描述:

void RankLink(struct StuLink *head){int i=2;if(head==NULL){printf("学生数据为空!\n");printf("\n"); system("pause");    return;}head=SortLink(head,i);struct StuLink *p1=head,*p2;int n=1;while(p1){p1->mc=n;n++;if((p1!=head)&&((p1->cj)==(p2->cj))) p1->mc=p2->mc;p2=p1;p1=p1->next;}SaveToFile(head);
}

11. AnalysisLink 函数

函数首部:void AnalysisLink(struct StuLink *head,int *dj_add)

参数列表:
[1]head:用于表示首节点的地址
[2]dj_add:用于表示各个等级的人数数组
[3]p1:用于表示循环链表中的节点

返回值:无

实现功能:先判断链表是否为空,为空则退出函数。循环各节点,判断成绩且对应等级统计数递增

算法描述:

void AnalysisLink(struct StuLink *head,int *dj_add){if(head==NULL){printf("学生数据为空!\n");printf("\n"); system("pause"); return;}struct StuLink *p1=head;while(p1){if(p1->cj>=90) dj_add[0]++;else if(p1->cj>=80) dj_add[1]++;else if(p1->cj>=70) dj_add[2]++;else if(p1->cj>=60) dj_add[3]++;else  dj_add[5]++;p1=p1->next;}
}

12. OutputLink_1 函数

函数首部:void OutputLink_1(struct StuLink *head,int i)

参数列表:
[1]head:用于表示首节点的地址
[2]p1:用于表示循环链表节点的地址

返回值:无

实现功能:先判断链表是否为空,为空则退出函数。循环各节点,输出信息

算法描述:

void  OutputLink_1(struct StuLink *head,int i){if(head==NULL){printf("学生数据为空!\n");printf("\n"); system("pause");  return;}head=SortLink(head,i);struct StuLink *p1=head;printf("所有学生信息为:\n");printf("学号  姓名      性别 成绩  等级  名次\n");while(p1){printf("%-6d%-10s",p1->xh,p1->xm);if(p1->xb==1) printf("男    ");else printf("女    "); printf("%-6d%-6c%-6d\n",p1->cj,p1->dj,p1->mc);p1=p1->next;}
}

13. OutputLink_2 函数

函数首部:void OutputLink_2(struct StuLink *head,int i)

参数列表:
[1]head:用于表示首节点的地址
[2]i:用于表示排序的升降序
[3]sum:用于表示学生总数
[4]n:用于表示当前输出个数
[5]num1:用于表示菜单选择
[6]page_sum:用于表示总页数
[7]page_now:用于表示当前页数
[8]pf_num:用于表示当前输出的个数,控制不超过 10 个

返回值:无

实现功能:先判断链表是否为空,为空则退出函数。先输出第一页,判断总人数,是否有下一页, 无则退出函数,有则继续。接收输入选择功能数字,判断数字时候合理,不合理重新输入。使用 switch 跳到对应功能。1:用上次输出的当前页数*10-20 就等于“上一页”的第一个的学生个数,再用 n 控制 p1 循环到此处进行输出。2:跟着 p1 继续输出。3:输出第一页。4:用(sum/10)*10 就等于最后一页的第一 个学生个数,用 p1 循环到此处,输出即可。

算法描述:

void  OutputLink_2(struct StuLink *head,int i){if(head==NULL){printf("学生数据为空!\n");printf("\n"); system("pause");  return;}head=SortLink(head,i);
//  sum:学生总数 n:当前输出个数  int n=1,num1,sum=0,page_sum,page_now=1,pf_num=0;struct StuLink *p1=head;while(p1){sum++;p1=p1->next;}p1=head;page_sum=sum/10+1;system("cls");printf("学号  姓名      性别 成绩  等级  名次\n");pf_num=1;while(p1&&pf_num<=10){printf("%-6d%-10s",p1->xh,p1->xm);if(p1->xb==1) printf("男    ");else printf("女    "); printf("%-6d%-6c%-6d\n",p1->cj,p1->dj,p1->mc);pf_num++;p1=p1->next;}if(sum<=10){printf("\n只有一页,暂无上下页功能\n"); system("pause"); return ;}else{printf("\n          2-下一页  3-首页  4-尾页  5-返回上级\n");printf("            当前第%-2d页,共%-2d页\n",page_now,page_sum); scanf("%d",&num1);while(num1<2||num1>5){printf("请输入正确的数字: ");scanf("%d",&num1);}}while(1) {switch(num1){case 1:system("cls");p1=head;n=1;while(n<=page_now*10-20){p1=p1->next;n++;}printf("学号  姓名      性别 成绩  等级  名次\n");pf_num=1;while(p1&&pf_num<=10){printf("%-6d%-10s",p1->xh,p1->xm);if(p1->xb==1) printf("男    ");else printf("女    "); printf("%-6d%-6c%-6d\n",p1->cj,p1->dj,p1->mc);pf_num++;p1=p1->next;}page_now--;                                          //当前页数-1if(page_now==1){printf("\n          2-下一页  3-首页  4-尾页  5-返回上级\n");printf("            当前第%-2d页,共%-2d页\n",page_now,page_sum); scanf("%d",&num1);while(num1<2||num1>5){printf("请输入正确的数字: ");scanf("%d",&num1);}}else{printf("\n1-上一页  2-下一页  3-首页  4-尾页  5-返回上级\n");printf("            当前第%-2d页,共%-2d页\n"); scanf("%d",&num1);while(num1<1||num1>4){printf("请输入正确的数字: ");scanf("%d",&num1);}}break;case 2:system("cls");printf("学号  姓名      性别 成绩  等级  名次\n");pf_num=1;while(p1&&pf_num<=10){printf("%-6d%-10s",p1->xh,p1->xm);if(p1->xb==1) printf("男    ");else printf("女    "); printf("%-6d%-6c%-6d\n",p1->cj,p1->dj,p1->mc);pf_num++;p1=p1->next;}page_now++;                                          //当前页数+1 if(page_now==page_sum){printf("\n1-上一页            3-首页  4-尾页  5-返回上级\n");printf("            当前第%-2d页,共%-2d页\n",page_now,page_sum); scanf("%d",&num1);while(num1<1||num1>5||num1==2){printf("请输入正确的数字: ");scanf("%d",&num1);}}else{printf("\n1-上一页  2-下一页  3-首页  4-尾页  5-返回上级\n");printf("            当前第%-2d页,共%-2d页\n"); scanf("%d",&num1);while(num1<1||num1>5){printf("请输入正确的数字: ");scanf("%d",&num1);}}break;case 3:system("cls");p1=head;page_now=1;printf("学号  姓名      性别 成绩  等级  名次\n");pf_num=1;while(p1&&pf_num<=10){printf("%-6d%-10s",p1->xh,p1->xm);if(p1->xb==1) printf("男    ");else printf("女    "); printf("%-6d%-6c%-6d\n",p1->cj,p1->dj,p1->mc);pf_num++;p1=p1->next;}printf("\n          2-下一页  3-首页  4-尾页  5-返回上级\n");printf("            当前第%-2d页,共%-2d页\n",page_now,page_sum); scanf("%d",&num1);while(num1<2||num1>5){printf("请输入正确的数字: ");scanf("%d",&num1);}break;case 4:system("cls");p1=head;page_now=page_sum;n=1;while(n<=(sum/10)*10){p1=p1->next;n++;}printf("学号  姓名      性别 成绩  等级  名次\n");pf_num=1;while(p1&&pf_num<=10){printf("%-6d%-10s",p1->xh,p1->xm);if(p1->xb==1) printf("男    ");else printf("女    "); printf("%-6d%-6c%-6d\n",p1->cj,p1->dj,p1->mc);pf_num++;p1=p1->next;}printf("\n1-上一页            3-首页  4-尾页  5-返回上级\n");printf("            当前第%-2d页,共%-2d页\n",page_now,page_sum); scanf("%d",&num1);while(num1<1||num1>5||num1==2){printf("请输入正确的数字: ");scanf("%d",&num1);}break;case 5:break;}if(num1==5) break;}
}

四、运行界面

一:主菜单

二:二级菜单——数据维护

  1. 数据插入

  2. 数据修改

  3. 数据删除

三:二级菜单——数据查询

  1. 学号查询

  1. 不及格学生查询

四:二级菜单——统计分析

  1. 成绩名次计算:无输出
  2. 成绩频次分析

五:二级菜单——报表输出

  1. 排序显示学生信息

​ 学号升序:

​ 成绩降序:

  1. 分页显示学生信息

六、退出

五、源代码

注意要在同个目录新建一个student.dat文件

#include <stdio.h>
#include <stdlib.h>
#include <string.h>//枚举
enum sex{women,man};
struct StuLink{int  xh;                   //学号char xm[20];               //姓名 enum sex  xb;              //性别 int  cj;                   //成绩,范围[0,100]    前四个为输入项 char dj;                   //等级int  mc;                   //名次struct StuLink *next;      //下一项
};
char sex[][3]={"女","男"};     //用于输出“男女”中文字符
int size=sizeof(struct StuLink);  //节点字节大小 void main(){//  声明变量int menu1,menu2;        //menu1:一级菜单 menu2:二级菜单  int i=0,n,dj_add[5]={0,0,0,0,0};struct StuLink *head=NULL,*pw;   //*head:学生信息链表头指针 pw:尾节点 //  声明函数
// 从数据文件中逐行读取学生信息生成学生链表,返回头指针 struct StuLink *ReadFromFile();
//  先将学生链表按学号升序排序,再将学生链表中的数据逐行保存到数据文件void SaveToFile(struct StuLink *head);
//  SortLink函数:按指定数据项的顺序【1:学号(升序)】或者【2:成绩(降序)】对学生链表进行排序 struct StuLink *SortLink(struct StuLink *head,int i);
//  InsertNode函数:在链表尾插入一个新结点。新结点的学号是链表中最大学号加1,姓名和成绩从键盘输入
//  (注意:成绩必须在[0,100]区间的整数),根据成绩计算等级。
//  注意:插入结点会导致链表中各结点名次的变化。struct StuLink *InsertNode(struct StuLink *pw);
//  EditNode函数:修改链表中指定学号的结点(学号不能修改,成绩必须在[0,100]区间的整数)
//  注意:当修改成绩时会导致等级和名次的变化void EditNode(struct StuLink *head);
//DeleteNode函数:删除链表中指定学号的结点。注意:删除结点会导致链表中各结点名次的变化struct StuLink *DeleteNode(struct StuLink *head);
//  QueryNode函数:查询链表中指定学号的结点,并显示查询结果。
void QueryNode(struct StuLink *head);
//  QueryLink函数:查询链表中不及格的所有结点,并显示查询结果。
void QueryLink(struct StuLink *head);
//RankLink函数:计算链表中每个结点的名次。名次规则:按成绩降序排名,从第1名开始依次排名,
//若出现并列名次,则名次需要叠加。例如,若出现5个并列第1名,则没有第2名,下一个名次是第6名,依此类推。
void RankLink(struct StuLink *head);
//AnalysisLink函数:统计并返回各等级人数。等级标准:
//A:90及以上        B:80及以上      C:70及以上      D:60及以上      E:60以下
void AnalysisLink(struct StuLink *head,int *dj_add);
//OutputLink_1函数:按指定数据项的顺序【1:学号(升序)】或者【2:成绩(降序)】输出学生成绩表、各等级人数。
//学生成绩表每行输出一个学生信息(依次为学号、姓名、性别、成绩、等级和名次,各项间以1个空格隔开),
//各等级人数分行输出。
void  OutputLink_1(struct StuLink *head,int i);
//OutputLink_2函数:分页显示全部学生的信息。
//分页功能:每页显示10个学生信息,有上一页、下一页、首页和最后一页的翻页功能。
void  OutputLink_2(struct StuLink *head,int i);//   执行语句head=ReadFromFile();     //读取文件到链表,获取头指针 // 菜单while(1){system("cls");                  //清控制台,Windows printf("========================================\n");//40个=printf("=                                      =\n");printf("=           学生成绩管理程序           =\n");printf("=                              by:xxx =\n"); printf("========================================\n");printf("=                                      =\n");printf("=        1-数据维护  2-数据查询        =\n");printf("=        3-统计分析  4-报表输出        =\n");printf("=                0-退出                =\n");printf("=                                      =\n");printf("========================================\n");
//      printf("\n");printf("请选择:");scanf("%d",&menu1); switch(menu1){                 //一级菜单 case 1:while(1){                      //循环输出二级菜单 system("cls");printf("\n");printf("========================================\n");printf("=                                      =\n");printf("=        1-数据插入  2-数据修改        =\n");printf("=        3-数据删除  0-返回上级        =\n");printf("=                                      =\n");printf("========================================\n");printf("请选择:");scanf("%d",&menu2); switch(menu2){      //二级菜单 case 1:printf("请输入要插入的学生个数(n>0): "); scanf("%d",&n);while(n<=0){printf("!!!请输入正确的学生个数!!!: ");scanf("%d",&n);}pw=head;if(pw){while(pw->next)   //获取尾部节点 pw=pw->next;}for(i=0;i<n;i++){pw=InsertNode(pw);if(head==NULL) head=pw;}//   计算名次RankLink(head);
//                          SaveToFile(head);       break;case 2:EditNode(head);//  计算名次RankLink(head);
//                          SaveToFile(head);break;case 3:head=DeleteNode(head);// 计算名次RankLink(head);
//                          SaveToFile(head);   break;case 0:break;}if(menu2==0) break;}break;case 2:while(1){                      //循环输出二级菜单 system("cls");printf("\n");printf("========================================\n");printf("=                                      =\n");printf("=1-学号查询 2-不及格学生查询 0-返回上级=\n");printf("=                                      =\n");printf("========================================\n");printf("请选择:");scanf("%d",&menu2); switch(menu2){      //二级菜单 case 1:QueryNode(head);printf("\n"); system("pause");break;case 2:QueryLink(head); printf("\n"); system("pause");break;case 0:break;}if(menu2==0) break;}break;case 3:while(1){                      //循环输出二级菜单 system("cls");printf("\n");printf("========================================\n");printf("=                                      =\n");printf("=    1-成绩名次计算  2-成绩频次分析    =\n");printf("=              0-返回上级              =\n");printf("=                                      =\n");printf("========================================\n");printf("请选择:");scanf("%d",&menu2); switch(menu2){      //二级菜单 case 1:RankLink(head);break;case 2:AnalysisLink(head,dj_add);printf("'A'有%d人;'B'有%d人,'C'有%d人,'D'有%d人,'E'有%d人,共有%d人\n",dj_add[0],dj_add[1],dj_add[2],dj_add[3],dj_add[4],dj_add[0]+dj_add[1]+dj_add[2]+dj_add[3]+dj_add[4]); printf("\n"); system("pause"); break;case 0:break;}if(menu2==0) break;}break;case 4:while(1){                      //循环输出二级菜单 system("cls");printf("\n");printf("========================================\n");printf("=                                      =\n");printf("=1-排序显示学生信息  2-分页显示学生信息=\n");printf("=              0-返回上级              =\n");printf("=                                      =\n");printf("========================================\n");printf("请选择:");scanf("%d",&menu2); switch(menu2){      //二级菜单 case 1:printf("请选择按【1:学号(升序)】或者【2:成绩(降序)】输出学生成绩表:");scanf("%d",&i);while((i!=1)&&(i!=2)){printf("!!!请选择正确选项!!!1 or 2 : ");scanf("%d",&i);}OutputLink_1(head,i);printf("\n"); system("pause"); break;case 2:printf("请选择按【1:学号(升序)】或者【2:成绩(降序)】输出学生成绩表:");scanf("%d",&i);while((i!=1)&&(i!=2)){printf("!!!请选择正确选项!!!1 or 2 : ");scanf("%d",&i);}OutputLink_2(head,i);break;case 0:break;}if(menu2==0) break;}break;case 0:printf("========================================\n");printf("=                                      =\n");printf("=        你已经退出学生管理系统        =\n");printf("=                                      =\n");printf("========================================\n");return;       //退出main函数 }} } //  自 定 义 函 数
// 从数据文件中逐行读取学生信息生成学生链表,返回头指针
struct StuLink *ReadFromFile(){FILE *fp;                           //指向student.dat文件 struct StuLink *p1,*p2,*head=NULL;  //head:头节点  p1:开辟新节点  p2:尾节点 char ch;if((fp=fopen("student.dat","r"))==NULL){   //读开student.dat printf("打开student.dat失败\n");exit(0); } ch=fgetc(fp);                               //读取文件第一个字符if(ch==EOF){                                //EOF文件终止符printf("文件为空\n");return head;  }else{rewind(fp);                            // 将fp的地址重置为文件开头}while(!feof(fp)){if((p1=(struct StuLink *)malloc(size))==NULL) {printf("不能成功分配储存块");exit(0);}p1->next=NULL;if(head==NULL)  head=p1;        //首节点 else p2->next=p1;     //非首节点,表尾插入新节点 p2=p1;                    // p2指向新的表尾结点 fscanf(fp,"%d %s %d %d %s %d\n",&p1->xh,p1->xm,&p1->xb,&p1->cj,&p1->dj,&p1->mc);
//      读取\n是防止fp以为文件未完 printf("%-5d%-10s%-5d%-5d%-5c%-5d\n",p1->xh,p1->xm,p1->xb,p1->cj,p1->dj,p1->mc);}fclose(fp);                                 //关闭student.datreturn head;
} //    SortLink函数:按指定数据项的顺序【1:学号(升序)】或者【2:成绩(降序)】对学生链表进行排序struct StuLink *SortLink(struct StuLink *head,int i){if(head==NULL)return head;
//      使用交换数据的形式交换两个节点 int xh,xb,cj,mc;char xm[20],dj;
//      p1:被比较节点  p2:比较节点  p3:快速排序储存节点 struct StuLink *p1=head,*p2=head->next,*p3=p1;switch(i){case 1:
//              快速排序while(p1->next){p2=p1->next;p3=p1;while(p2){if(p3->xh>p2->xh) p3=p2;p2=p2->next;}if(p3->xh<p1->xh){xh=p3->xh;  xb=p3->xb;cj=p3->cj;  mc=p3->mc;strcpy(xm,p3->xm);  dj=p3->dj;p3->xh=p1->xh;  p3->xb=p1->xb;p3->cj=p1->cj;  p3->mc=p1->mc;strcpy(p3->xm,p1->xm);  p3->dj=p1->dj;p1->xh=xh;  p1->xb=xb;p1->cj=cj;  p1->mc=mc;strcpy(p1->xm,xm);  p1->dj=dj;} p1=p1->next;} break;case 2:
//              快速排序while(p1->next){p2=p1->next;p3=p1;while(p2){if(p3->cj<p2->cj) p3=p2;p2=p2->next;}if(p3->cj>p1->cj){xh=p3->xh;  xb=p3->xb;cj=p3->cj;  mc=p3->mc;strcpy(xm,p3->xm);  dj=p3->dj;p3->xh=p1->xh;  p3->xb=p1->xb;p3->cj=p1->cj;  p3->mc=p1->mc;strcpy(p3->xm,p1->xm);  p3->dj=p1->dj;p1->xh=xh;  p1->xb=xb;p1->cj=cj;  p1->mc=mc;strcpy(p1->xm,xm);  p1->dj=dj;} p1=p1->next;} break;} return head;}//  先将学生链表按学号升序排序,再将学生链表中的数据逐行保存到数据文件void SaveToFile(struct StuLink *head){FILE *fp;int i=1;head=SortLink(head,i);struct StuLink *p=head;if((fp=fopen("student.dat","w"))==NULL){printf("写开文件失败!");exit(0);}while(p){//          写入文件 fprintf(fp,"%d %s %d %d %c %d\n",p->xh,p->xm,p->xb,p->cj,p->dj,p->mc);p=p->next;}fclose(fp); }//   InsertNode函数:在链表尾插入一个新结点。新结点的学号是链表中最大学号加1,姓名和成绩从键盘输入
//  (注意:成绩必须在[0,100]区间的整数),根据成绩计算等级。
//  注意:插入结点会导致链表中各结点名次的变化。
struct StuLink *InsertNode(struct StuLink *pw){struct StuLink *p1;    //pw:原链表尾节点    p1:开辟新节点 if((p1=(struct StuLink *)malloc(size))==NULL) {printf("不能成功分配储存块\n");exit(0);}p1->next=NULL;if(pw)p1->xh=pw->xh+1;else p1->xh=1;char xm[20];printf("请依次输入姓名、性别(男1女0)、成绩[0,100]:  ");scanf("%s%d%d",xm,&p1->xb,&p1->cj);while(p1->xb!=0&&p1->xb!=1){printf("! ! ! 性别只能是1或0,请重新输入性别1:男    0:女   ");scanf("%d",&p1->xb); }while(p1->cj<0 || p1->cj>100){printf("! ! ! 成绩范围是0~100,请重新输入成绩   ");scanf("%d",&p1->cj); }strcpy(p1->xm,xm);//  p1->mc=1;  // 名次暂时命名为1 if(p1->cj>=90) p1->dj='A';else if(p1->cj>=80)  p1->dj='B';else if(p1->cj>=70)  p1->dj='C';else if(p1->cj>=60)  p1->dj='D';else p1->dj='E';if(pw==NULL)   pw=p1;else{pw->next=p1;    pw=pw->next;}return pw;
}// EditNode函数:修改链表中指定学号的结点(学号不能修改,成绩必须在[0,100]区间的整数)
//  注意:当修改成绩时会导致等级和名次的变化
void EditNode(struct StuLink *head){if(head==NULL){printf("学生数据为空!\n");printf("\n"); system("pause");    return;}struct StuLink *p1=head;char xm[20];int n,re;printf("请输入你要修改的学生信息的学号:");scanf("%d",&n) ;while(p1){if(p1->xh==n){break;}else{p1=p1->next;}}if(p1){printf("你要修改的学生信息为:\n");printf("学号  姓名      性别  成绩  等级  名次   ##男1女0##\n");printf("%-6d%-10s%-6d%-6d%-6c%-6d\n",p1->xh,p1->xm,p1->xb,p1->cj,p1->dj,p1->mc);} else{printf("你输入的学号有误!\n");printf("\n"); system("pause"); return;} printf("请选择要修改的数据项:0-不修改 1-姓名 2-性别 3-成绩  "); scanf("%d",&re);while(re<0||re>3){printf("输入有误!重新输入: ");scanf("%d",&re);}switch(re){case 0:break;case 1:printf("请输出新的姓名:");scanf("%s",xm);strcpy(p1->xm,xm);break;case 2:printf("请输入新的性别:");scanf("%d",&p1->xb);while(p1->xb!=0&&p1->xb!=1){printf("! ! ! 性别只能是1或0,请重新输入性别1:男    0:女   ");scanf("%d",&p1->xb); }break;case 3:printf("请输入新的成绩:");scanf("%d",&p1->cj);while(p1->cj<0 || p1->cj>100){printf("! ! ! 成绩范围是0~100,请重新输入成绩   ");scanf("%d",&p1->cj); }if(p1->cj>=90) p1->dj='A';else if(p1->cj>=80)  p1->dj='B';else if(p1->cj>=70)  p1->dj='C';else if(p1->cj>=60)  p1->dj='D';else p1->dj='E';break;   }
}//DeleteNode函数:删除链表中指定学号的结点。注意:删除结点会导致链表中各结点名次的变化
struct StuLink *DeleteNode(struct StuLink *head){if(head==NULL){printf("学生数据为空!\n");printf("\n"); system("pause");   return head;}struct StuLink *p1=head,*p2;int del_xh;printf("请输入要删除的学号:");scanf("%d",&del_xh); while((p1->xh!=del_xh)&&(p1->next!=NULL)){p2=p1;p1=p1->next;} if(p1->xh==del_xh){   //找到 if(head==p1) head=head->next;   //首节点 else p2->next=p1->next;         //非首节点 free(p1); printf("删除成功!\n");}else printf("未找到此学号对应节点!\n");printf("\n"); system("pause"); return head;
}// QueryNode函数:查询链表中指定学号的结点,并显示查询结果。
void QueryNode(struct StuLink *head){if(head==NULL){printf("学生数据为空!\n");printf("\n"); system("pause");   return;}int query_xh;struct StuLink *p1=head,*p2;printf("请输入要查询的学生学号:");scanf("%d",&query_xh); while((p1->xh!=query_xh)&&(p1->next!=NULL)){p2=p1;p1=p1->next;} if(p1->xh==query_xh){           //找到 printf("查找结果为:\n"); printf("学号:%-5d姓名:%-10s成绩:%-5d等级:%-5c名次:%-5d",p1->xh,p1->xm,p1->cj,p1->dj,p1->mc);if(p1->xb==1) printf("性别:男\n");else printf("性别:女\n"); }else printf("未找到该学号对应学生!\n");
}// QueryLink函数:查询链表中不及格的所有结点,并显示查询结果。
void QueryLink(struct StuLink *head){if(head==NULL){printf("学生数据为空!\n");printf("\n"); system("pause");   return;}struct StuLink *p1=head;int n=0;while(p1){if(p1->cj<60){n++; if(n==1) printf("未及格学生信息为:\n"); printf("学号:%-5d姓名:%-10s成绩:%-5d等级:%-5c名次:%-5d",p1->xh,p1->xm,p1->cj,p1->dj,p1->mc);if(p1->xb==1) printf("性别:男\n");else printf("性别:女\n"); }p1=p1->next;}if(n==0) printf("没有不及格学生!\n");
}//RankLink函数:计算链表中每个结点的名次。名次规则:按成绩降序排名,从第1名开始依次排名,
//若出现并列名次,则名次需要叠加。例如,若出现5个并列第1名,则没有第2名,下一个名次是第6名,依此类推。
void RankLink(struct StuLink *head){int i=2;if(head==NULL){printf("学生数据为空!\n");printf("\n"); system("pause");   return;}head=SortLink(head,i);struct StuLink *p1=head,*p2;int n=1;while(p1){p1->mc=n;n++;if((p1!=head)&&((p1->cj)==(p2->cj))) p1->mc=p2->mc;p2=p1;p1=p1->next;}SaveToFile(head);
}//AnalysisLink函数:统计并返回各等级人数。等级标准:
//A:90及以上        B:80及以上      C:70及以上      D:60及以上      E:60以下
void AnalysisLink(struct StuLink *head,int *dj_add){if(head==NULL){printf("学生数据为空!\n");printf("\n"); system("pause");    return;}struct StuLink *p1=head;while(p1){if(p1->cj>=90) dj_add[0]++;else if(p1->cj>=80) dj_add[1]++;else if(p1->cj>=70) dj_add[2]++;else if(p1->cj>=60) dj_add[3]++;else  dj_add[5]++;p1=p1->next;}
}//OutputLink_1函数:按指定数据项的顺序【1:学号(升序)】或者【2:成绩(降序)】输出学生成绩表、各等级人数。
//学生成绩表每行输出一个学生信息(依次为学号、姓名、性别、成绩、等级和名次,各项间以1个空格隔开),
//各等级人数分行输出。
void  OutputLink_1(struct StuLink *head,int i){if(head==NULL){printf("学生数据为空!\n");printf("\n"); system("pause"); return;}head=SortLink(head,i);struct StuLink *p1=head;printf("所有学生信息为:\n");printf("学号  姓名      性别 成绩  等级  名次\n");while(p1){printf("%-6d%-10s",p1->xh,p1->xm);if(p1->xb==1) printf("男    ");else printf("女    "); printf("%-6d%-6c%-6d\n",p1->cj,p1->dj,p1->mc);p1=p1->next;}
}//OutputLink_2函数:分页显示全部学生的信息。
//分页功能:每页显示10个学生信息,有上一页、下一页、首页和最后一页的翻页功能。
void  OutputLink_2(struct StuLink *head,int i){if(head==NULL){printf("学生数据为空!\n");printf("\n"); system("pause"); return;}head=SortLink(head,i);
//  sum:学生总数 n:当前输出个数  int n=1,num1,sum=0,page_sum,page_now=1,pf_num=0;struct StuLink *p1=head;while(p1){sum++;p1=p1->next;}p1=head;page_sum=sum/10+1;system("cls");printf("学号  姓名      性别 成绩  等级  名次\n");pf_num=1;while(p1&&pf_num<=10){printf("%-6d%-10s",p1->xh,p1->xm);if(p1->xb==1) printf("男    ");else printf("女    "); printf("%-6d%-6c%-6d\n",p1->cj,p1->dj,p1->mc);pf_num++;p1=p1->next;}if(sum<=10){printf("\n只有一页,暂无上下页功能\n"); system("pause"); return ;}else{printf("\n          2-下一页  3-首页  4-尾页  5-返回上级\n");printf("            当前第%-2d页,共%-2d页\n",page_now,page_sum); scanf("%d",&num1);while(num1<2||num1>5){printf("请输入正确的数字: ");scanf("%d",&num1);}}while(1) {switch(num1){case 1:system("cls");p1=head;n=1;while(n<=page_now*10-20){p1=p1->next;n++;}printf("学号  姓名      性别 成绩  等级  名次\n");pf_num=1;while(p1&&pf_num<=10){printf("%-6d%-10s",p1->xh,p1->xm);if(p1->xb==1) printf("男    ");else printf("女    "); printf("%-6d%-6c%-6d\n",p1->cj,p1->dj,p1->mc);pf_num++;p1=p1->next;}page_now--;                                          //当前页数-1if(page_now==1){printf("\n          2-下一页  3-首页  4-尾页  5-返回上级\n");printf("            当前第%-2d页,共%-2d页\n",page_now,page_sum); scanf("%d",&num1);while(num1<2||num1>5){printf("请输入正确的数字: ");scanf("%d",&num1);}}else{printf("\n1-上一页  2-下一页  3-首页  4-尾页  5-返回上级\n");printf("            当前第%-2d页,共%-2d页\n"); scanf("%d",&num1);while(num1<1||num1>4){printf("请输入正确的数字: ");scanf("%d",&num1);}}break;case 2:system("cls");printf("学号  姓名      性别 成绩  等级  名次\n");pf_num=1;while(p1&&pf_num<=10){printf("%-6d%-10s",p1->xh,p1->xm);if(p1->xb==1) printf("男    ");else printf("女    "); printf("%-6d%-6c%-6d\n",p1->cj,p1->dj,p1->mc);pf_num++;p1=p1->next;}page_now++;                                          //当前页数+1 if(page_now==page_sum){printf("\n1-上一页            3-首页  4-尾页  5-返回上级\n");printf("            当前第%-2d页,共%-2d页\n",page_now,page_sum); scanf("%d",&num1);while(num1<1||num1>5||num1==2){printf("请输入正确的数字: ");scanf("%d",&num1);}}else{printf("\n1-上一页  2-下一页  3-首页  4-尾页  5-返回上级\n");printf("            当前第%-2d页,共%-2d页\n"); scanf("%d",&num1);while(num1<1||num1>5){printf("请输入正确的数字: ");scanf("%d",&num1);}}break;case 3:system("cls");p1=head;page_now=1;printf("学号  姓名      性别 成绩  等级  名次\n");pf_num=1;while(p1&&pf_num<=10){printf("%-6d%-10s",p1->xh,p1->xm);if(p1->xb==1) printf("男    ");else printf("女    "); printf("%-6d%-6c%-6d\n",p1->cj,p1->dj,p1->mc);pf_num++;p1=p1->next;}printf("\n          2-下一页  3-首页  4-尾页  5-返回上级\n");printf("            当前第%-2d页,共%-2d页\n",page_now,page_sum); scanf("%d",&num1);while(num1<2||num1>5){printf("请输入正确的数字: ");scanf("%d",&num1);}break;case 4:system("cls");p1=head;page_now=page_sum;n=1;while(n<=(sum/10)*10){p1=p1->next;n++;}printf("学号  姓名      性别 成绩  等级  名次\n");pf_num=1;while(p1&&pf_num<=10){printf("%-6d%-10s",p1->xh,p1->xm);if(p1->xb==1) printf("男    ");else printf("女    "); printf("%-6d%-6c%-6d\n",p1->cj,p1->dj,p1->mc);pf_num++;p1=p1->next;}printf("\n1-上一页            3-首页  4-尾页  5-返回上级\n");printf("            当前第%-2d页,共%-2d页\n",page_now,page_sum); scanf("%d",&num1);while(num1<1||num1>5||num1==2){printf("请输入正确的数字: ");scanf("%d",&num1);}break;case 5:break;}if(num1==5) break;}
}

C语言学生成绩管理系统详解相关推荐

  1. C语言:学生信息管理系统(详解+源码)

    当你搜到这篇文章的时候,相信你可能正在为期末大作业而愁眉不展,下面的代码只需要三步就能实现: 复制.粘贴.编译运行. 不过在实现的同时还是希望正在学习的你好好理解一下,真正体会到编程的乐趣,加油! 如 ...

  2. 用C语言学生成绩数据库排序功能设计,[c语言学生成绩管理系统]C语言学生成绩管理系统实验报告...

    篇一 : C语言学生成绩管理系统实验报告 实 验 四:结构体(6学时) 实验目的: 1.更加灵活的使用数组作为函数参数: 2.初步掌握开发一个小型实用系统的基本方法: 3.初步掌握书写程序设计开发文档 ...

  3. c语言按给定成绩查询,C语言学生成绩管理系统(简易版)

    #include #include #include int readstudents(struct students stu[]); //读取学生信息 int readsexcode(struct ...

  4. C语言学生成绩管理系统(课程设计报告书)

    今天再跟大家分享一份课程设计报告:C语言学生成绩管理系统源码 程序设计组成框图: #include<stdio.h> #include<conio.h> #include< ...

  5. C语言学生成绩管理系统源代码

    分享:C语言学生成绩管理系统设计 <C语言程序设计>实训报告 点击查看 ----> C语言学生成绩管理系统(课程设计报告书) 扫描下方公众号,发送 成绩系统 4个字,获取下载源码. ...

  6. c语言成绩管理系统教程,C语言学生成绩管理系统教程.doc

    C语言学生成绩管理系统教程 实训报告 题 目: 学生成绩管理系统院 系: 专 业: 姓 名: 学 号: 指导教师: 日 期: 目录 TOC \o "1-3" \h \z \u HY ...

  7. c语言成绩管理系统报告书,C语言学生成绩管理系统实验报告

    <C语言学生成绩管理系统实验报告>由会员分享,可在线阅读,更多相关<C语言学生成绩管理系统实验报告(22页珍藏版)>请在人人文库网上搜索. 1.学生成绩管理系统实验报告实验名称 ...

  8. C语言 学生成绩管理系统 带登录界面

    C语言 学生成绩管理系统 带登录界面 C语言课程设计 思路 部分展示 代码片段 C语言课程设计 先上要求: 思路 为了方便简单,直接利用结构体数组来存储学生学生,最后根据功能编写函数即可. 部分展示 ...

  9. c语言学生成绩管理系统(增、删、查、改、排序、分析优秀及格率等)

    复制时运行出错请看这里:c语言学生成绩管理系统 添加公众号回复 学管 免费获取源代码 代做可私聊 c语言学生成绩管理系统(增.删.查.改.排序.分析优秀及格率等)详细内容 一.功能描述 实现学生基本信 ...

最新文章

  1. R语言ggplot2可视化彩色水平条形图并基于条形长度和数值标签长度、自定义最优化配置标签在条形内部或者条形外部
  2. nginx_gzip压缩提升网站的传输速度
  3. Windows Vista for Developers——第三部分补充:控件和桌面窗口管理器
  4. Python sorted 和 sort() 的区别
  5. 开始复习下sql,常用SQL语句示例(一)
  6. 【Linux系统编程】特殊进程之守护进程
  7. 发布 ASP.NET Core 应用
  8. ubuntu 14.04中文显示乱码问题
  9. PAT乙类1008之数组元素循环右移问题
  10. 还在随缘炼丹?一文带你详尽了解机器学习模型可解释性的奥秘
  11. 圣诞主题的图标素材,为节日做好准备
  12. vue.js 添加 fastclick的支持
  13. OpenHarmony学习笔记——编辑器访问Linux服务器进行编译
  14. 20201216指数估值表
  15. 中外十大武侠片排行榜
  16. JavaScript中sort()对数组数字项函数function(a,b)返回值为a-b即为升序排列的细解
  17. nn.module 看图搭建网络
  18. 上海it外包公司排名_it外包公司排行榜怎么来的?
  19. 微信小程序JS 字符串string与arraybuffer的相互转换
  20. android 7双排设置菜单,双排状态栏布局教程

热门文章

  1. 千牛文件在服务器上,千牛挂在云服务器
  2. 暗影精灵5风扇怎么调_惠普暗影精灵5super散热改装
  3. 概率论与随机过程笔记(1):样本空间与概率
  4. C小白Jeff头秃番外篇一
  5. 虚拟机玩转 Veritas NetBackup(NBU)之 Linux 配置 NBU 客户端
  6. 银行核心系统入门简介
  7. 【毕业设计】stm32机器视觉的人脸识别系统 - 单片机 物联网 嵌入式
  8. JavaScript - ES6 - latest - 学习/实践
  9. 电脑无法开机一直滴滴响
  10. 第42届ACM国际大学生程序设计竞赛 亚洲区域赛 西安站 总结