C语言学生成绩管理系统详解

article/2025/10/27 9:25:53

文章目录

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

源代码请直接跳到最后

引言:最近写了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;}
}

http://chatgpt.dhexx.cn/article/TTBo1k37.shtml

相关文章

学生成绩管理系统 C语言

基础篇问题&#xff1a; 1.输出如下菜单&#xff1a; *********************学生成绩管理系统******************* * 1 成绩录入 2 成绩查询 3 计算平均分 * * 4 计算最高分 5 排名 6 退出 * ******************************…

C语言编程学生成绩管理系统

目录 一、介绍 二、功能 1.录入学生 2.删除学生信息 3.修改学生信息 4.查询学生信息 5.所有学生信息 6.成绩排序 7.退出程序 三、代码 1.主函数 2.头文件 3.函数封装库 一、介绍 利用C语言&#xff0c;运用链表、指针、封装函数等基本知识实现一个学生管理系统。通…

C语言学生成绩管理系统

制作学生成绩管理系统&#xff0c;可以实现以下功能&#xff1a; 每条记录包括&#xff1a;学号、姓名、专业和5门课程的成绩&#xff1b;能够实现添加、删除、修改功能&#xff1b;能够计算某学生的总分和平均分&#xff1b;能按照总分排序输出&#xff1b; 利用C语言的基本…

c语言成绩管理系统

关注微信公众号每日新觉&#xff0c;私聊作者获取提取密码点击下面链接&#xff0c;私聊作者获取提取密码。https://mp.weixin.qq.com/s/QgRQ3YB2JqCvNOGQHQ57rA 作者每日新觉&#xff0c;是一名热爱技术和编程的年轻程序员。他在计算机科学和软件工程领域有着广泛的研究和实践…

c语言成绩管理系统1.0,c语言成绩管理系统完整附源码v1.0 免费版

c语言成绩管理系统拥有和hello word一样的江湖地位&#xff0c;初学C语言的朋友基本都会从管理系统开始入手学习&#xff0c;对于很多大学生来说更是如此&#xff0c;今天为大家带来的这款系统以及源码希望能对大家学习学C语言有所帮助&#xff0c;欢迎下载使用。 C语言介绍 C语…

C语言学生成绩管理系统(综合项目)

1. 这个代码主要实现以下功能&#xff1a; 2. 用到的主要参数有&#xff1a; 1.整型变量int n;用于储存学生人数和之后的循环判断。 2.字符串char name[][];用于储存姓名。 3.浮点型变量float score[];用于储存成绩。 4.长整型变量long ID[Max];用于储存学号。 3.…

【高级语言程序设计】c语言-学生成绩管理系统

c语言期末作业 声明&#xff1a;未经允许&#xff0c;请勿转载 学生成绩管理系统 本系统能够对学生成绩管理功能&#xff0c;包括&#xff1a; 1.对多个学生成绩进行管理&#xff0c;至少10个学生。 2.每个学生至少3门课程。 3.对每个学生大学期间的成绩进行记录。 4.修改学生…

班级成绩管理系统(C语言)

文章目录 一、设计任务与目标二、实现功能三、程序源码四、效果展示 一、设计任务与目标 对一个有N个学生的班级&#xff0c;每个学生有M门课程。该系统实现对班级成绩的录入、显示、修改、排序、保存等操作的管理。 二、实现功能 &#xff08;1&#xff09;本系统采用一个结…

C语言:学生成绩管理系统

目录 一&#xff1a;功能概述&#xff1a; 二&#xff1a;实现&#xff1a; 1.主源文件 1.打印菜单&#xff01; 2.构建管理系统的框架&#xff1a; 二&#xff1a;辅源文件 1.使用结构体&#xff0c;方便后面的编写 2.输入学生信息 3.输出学生基本信息 3.按姓名查询 3.…

C语言课程设计|学生成绩管理系统(含完整代码)

目录 前言 简介 学生信息录入功能 学生单个信息查询 查询全部学生信息 修改学生信息 删除学生信息 退出 完整代码 前言 在临近期末之际&#xff0c;相信好多初学C语言的同学都开始为写C语言课程设计这件事开始焦虑了吧&#xff1f;或许会不知所措&#xff0c;或许会…

matlab importdata不能读取全部数据问题

最近使用importdata函数不能读取全部数据&#xff0c;数据集315行&#xff0c;但是读取了197行&#xff0c;那就是197-198之间有问题&#xff0c;百度之后有了思路。由于没有找到具体的证据&#xff0c;所以这里说一下解决思路。 import可以导入很多文件类型&#xff0c;.dat文…

ImportError: cannot import name 'datasets'

初次使用python scikit-learn库时出现找不到模块的问题 from sklearn import datasets ImportError: cannot import name datasets类似问题链接&#xff1a; https://stackoverflow.com/questions/39280466/cant-import-datasets-with-scikit-learn 参考答案&#xff1a; 原因…

MATLAB输入、导入方式(手动输入,TXT文件,Excel导入)

目录 手动输入 input函数 自动输入 TXT导入数组 dir函数 importdata函数 Excel导入数组 手动输入 input函数 请求用户输入 语法 x input(number) %数值型str input(charnumber,s) %字符型&#xff0c;s不能改变 数值型进行演示 Pzeros(5,1); %建立零51矩阵进行储存…

1.数据的导入与导出

数据的导入与导出 更多MATLAB数据分析视频请点击&#xff0c;或者在网易云课堂上搜索《MATLAB数据分析与统计》 http://study.163.com/course/courseMain.htm?courseId1003615016 在用MATLAB进行编程时&#xff0c;不可避免的要涉及到数据的导入与导出&#xff0c;如果数据…

matlab读取数据文件

data1.txt: 0 3886.162 2200.938 141.240 1 3721.139 2208.475 141.152 2 3866.200 2198.936 141.126 3 3678.048 2199.191 141.250 4 3685.453 2203.726 141.241 分别采用load、importdata、textread、fscanf、textscan和fread函数读取文本数据文件。 dat1load(data1.t…

Python中库导入from . import 和from .. import 的使用方法

Python中库导入from . import 和from .. import 的使用方法 程序目录结构如下 from . import XX 和 from .. import XX 只能使用在子包中&#xff0c;例如上面的例子中&#xff0c;程序最外层是主程序app.py,程序有一个子包pack1&#xff0c;pack1下有a.py 和b.py两个文件&…

matlab inport data 作图,MATLAB使用importdata读取字符数据文件并绘图 值得收藏

本文首先使用importdata( )读取(导入)含有字符和数据的文本格式数据文件&#xff0c;然后介绍通过“.”数据名的方式读取结构数组中的数据&#xff0c;最后使用plot( )绘制折线图。 工具/材料 MATLAB struct 操作方法 01 第一&#xff0c;首先准备数据&#xff0c;下图txt数据文…

【MATLAB统计分析与应用100】案例001:matlab使用Importdata函数导入文本txt数据

配套实验数据包下载链接&#xff1a;订阅专栏后&#xff0c;从私信查收链接。 文章目录 1. 调用importdata函数读取文件中的数据2. 调用importdata函数读取文件数据&#xff0c;返回结构体变量x3. 调用importdata函数读取文件中的数据&#xff0c;用;作分隔符&#xff0c;返回字…

ImportError: No module named data

问题 明明在IDE&#xff08;如Pycharm&#xff09;中运行 check_file.py 正常。到了xshell使用python check_file.py方式运行时&#xff0c;就报ImportError: No module named data。 # check_file.py from data import scannet_util产生这个问题的原因是python的搜索路径导致…