目录
一、运行环境说明
操作系统: Windows系列
编译软件: Visual Studio Code
开发语言: C语言
二、主题题目要求
7) 统计管理
按照运动员信息、比赛项目信息的不同条件分别统计相应的参赛成绩、比赛人数等,统计的信息以列表形式显示,要求显示统计结果信息。
- 运动员信息:可以按照参赛编号、性别、所属学院等条件进行参赛成绩统计,统计满足条件对应的参赛成绩。例如,统计单个同学的参赛成绩,某个参赛编号的同学已经获得第一名1项,第二名2项,第三名0项;统计某个学院中运动员的参赛成绩,某个学院已经获得第一名2项,第二名1项,第三名3项,其中,男生/女生已经获得第一名1项,第二名0项,第三名2项等。
- 比赛项目信息:可以按照比赛项目编号、项目性别等,统计出满足条件对应的参赛人数。例如,某个比赛项目编号的参赛运动员总共10人,其中男生/女生总共5人等。
三、流程图
四、程序代码
struct athleteData
{
int athNum;//运动员编号
char athName[10];//姓名
char athsex[10];//性别
int athage;//年龄
char athcollege[10];//学院
char athremark[10];//备注
};
struct Linkathlete
{
int athNum;//运动员编号
char athName[10];//姓名
char athsex[10];//性别
int athage;//年龄
char athcollege[10];//学院
char athremark[10];//备注
struct Linkathlete *next;
};
struct matchData
{
int matNum;//比赛项目编号
char matName[10];//名称
char matsex[10];//项目性别
char mattime[10];//比赛时间
char matplace[10];//比赛地点
char matresult[10];//赛况
};
struct Linkmatch
{
int matNum;//比赛项目编号
char matName[10];//名称
char matsex[10];//项目性别
char mattime[10];//比赛时间
char matplace[10];//比赛地点
char matresult[10];//赛况
struct Linkmatch *next;
};
struct scoreData
{
int scoathlete;//运动员编号
int scomatch;//比赛项目编号
char scocollege[10];//学院
double scograde;//成绩
int scorank;//名次
};
struct Linkscore
{
int scoathlete;//运动员编号
int scomatch;//比赛项目编号
char scocollege[10];//学院
double scograde;//成绩
int scorank;//名次
struct Linkscore *next;
};
/*链表*/
struct Linkathlete *creadathleteList()
{
FILE *ptr;
struct athleteData athlete={0,"","",0,"",""};
struct Linkathlete *head,*p,*q;//创建结构体指针
if((ptr=fopen("athlete.dat","rb"))==NULL)
{
printf("不能打开文件 \n");
exit(0);
}
head = NULL;//创建链表的常规操作,表示头结点开始为空结点
p = NULL;//创建链表的常规操作, 当前读取结点
q = NULL;//创建链表的常规操作,当前读取备份结点
while(fread(&athlete,sizeof(athlete),1,ptr)!=0) //从文件中读信息存储在athlete中
{
p=(struct Linkathlete *)malloc(sizeof(struct Linkathlete));//
p->athNum=athlete.athNum;
strcpy(p->athName,athlete.athName);
strcpy(p->athsex,athlete.athsex);
p->athage=athlete.athage;
strcpy(p->athcollege,athlete.athcollege);
strcpy(p->athremark,athlete.athremark);
p->next=NULL;
if (head==NULL) //用于判断头结点是否为空
{
head=p;//head指向头结点
}
else
{
q->next=p;
}
q=p;
}
fclose(ptr);//关闭文件指针
return head;//链表的头结点
}
struct Linkmatch *creadmatchList()
{
FILE *ptr;
struct matchData match={0,"","","","",""};
struct Linkmatch *head,*p,*q;//创建结构体指针
if((ptr=fopen("match.dat","rb"))==NULL)
{
printf("不能打开文件 \n");
exit(0);
}
head = NULL;//创建链表的常规操作,表示头结点开始为空结点
p = NULL;//创建链表的常规操作, 当前读取结点
q = NULL;//创建链表的常规操作,当前读取备份结点
while(fread(&match,sizeof(match),1,ptr)!=0) //从文件中读信息存储在score中
{
p=(struct Linkmatch *)malloc(sizeof(struct Linkmatch));//申请内存空间
p->matNum=match.matNum;
strcpy(p->matName,match.matName);
strcpy(p->matsex,match.matsex);
strcpy(p->mattime,match.mattime);
strcpy(p->matplace,match.matplace);
strcpy(p->matresult,match.matresult);
p->next=NULL;
if (head==NULL) //用于判断头结点是否为空
{
head=p;//head指向头结点
}
else
{
q->next=p;
}
q=p;
}
fclose(ptr);//关闭文件指针
return head;//链表的头结点
}
struct Linkscore *creadscoreList()
{
FILE *ptr;
struct scoreData score={0,0,"",0.0,0};
struct Linkscore *head,*p,*q;//创建结构体指针
if((ptr=fopen("score.dat","rb"))==NULL)
{
printf("不能打开文件 \n");
exit(0);
}
head = NULL;//创建链表的常规操作,表示头结点开始为空结点
p = NULL;//创建链表的常规操作, 当前读取结点
q = NULL;//创建链表的常规操作,当前读取备份结点
while(fread(&score,sizeof(score),1,ptr)!=0) //从文件中读信息存储在score中
{
p=(struct Linkscore *)malloc(sizeof(struct Linkscore));//申请内存空间
p->scoathlete=score.scoathlete;
p->scomatch=score.scomatch;
strcpy(p->scocollege,score.scocollege);
p->scograde=score.scograde;
p->scorank=score.scorank;
p->next=NULL;
if (head==NULL) //用于判断头结点是否为空
{
head=p;//head指向头结点
}
else
{
q->next=p;
}
q=p;
}
fclose(ptr);//关闭文件指针
return head;//链表的头结点
}
/*统计信息*/
void countcollege()
{
struct Linkscore *head,*p,*q;
char tempcollege[10];
int fir=0;
int sec=0;
int thi=0;
int flag=0;
head=creadscoreList();
p=head;
printf("请输入要统计的学院名称;");
scanf("%s",tempcollege);
while(p!=NULL)//统计性别相同的
{
if(strcmp(p->scocollege,tempcollege)==0)
{
int scorank = p->scorank; // 获取成绩的名次
flag=1;
if(scorank==1)
{
fir=fir+1;
}
if(scorank==2)
{
sec=sec+1;
}
if(scorank==3)
{
thi=thi+1;
}
}
p=p->next;
}
if (flag==0)
{
printf("没有要统计的信息\n");
printf("%-10s",tempcollege);
}
else
{
printf("%-13s%-10s%-10s%-0s\n","学院","第一名:","第二名:","第三名:");
printf("%-13s%-10d%-10d%-10d\n",tempcollege,fir,sec,thi);
}
}
void countscore()
{
struct Linkscore *head,*p,*q;
int tempName;
int fir=0;
int sec=0;
int thi=0;
int flag=0;
head=creadscoreList();
p=head;
printf("请输入要统计的运动员(输入远动员编号);");
scanf("%d",&tempName);
while(p!=NULL)//统计性别相同的
{
if(tempName==p->scoathlete)
{
int scorank = p->scorank; // 获取成绩的名次
flag=1;
if(scorank==1)
{
fir=fir+1;
}
if(scorank==2)
{
sec=sec+1;
}
if(scorank==3)
{
thi=thi+1;
}
}
p=p->next;
}
if (flag==0)
{
printf("没有要统计的信息\n");
printf("%-10d",tempName);
}
else
{
printf("%-13s%-10s%-10s%-0s\n","远动员编号","第一名:","第二名:","第三名:");
printf("%-13d%-10d%-10d%-10d\n",tempName,fir,sec,thi);
}
}
void countathlete()
{
struct Linkathlete *head,*p;
char tempsex[10];
//统计一个人的成绩信息
int sum=0;
int flag=0;
head=creadathleteList();
p=head;
printf("请输入要统计的性别;");
scanf("%s",tempsex);
while(p!=NULL)//统计性别相同的
{
if(strcmp(p->athsex,tempsex)==0)
{
sum=sum+1;
flag=1;
}
p=p->next;
}
if (flag==0)
{
printf("没有要统计的信息\n");
printf("%-10s%d\n",tempsex,sum);
}
else
{
printf("%-10s%-0s\n","性别","个数");
printf("%-10s%d\n",tempsex,sum);
}
// printf("This is countRecord\n");//查询
}
void countname()
{
struct Linkmatch *head,*p;
char tempname[10];
//统计一个人的成绩信息
int summ=0;
int flag=0;
head=creadmatchList();
p=head;
printf("请输入要统计的参赛项目;");
scanf("%s",tempname);
while(p!=NULL)//统计性别相同的
{
if(strcmp(p->matName,tempname)==0)
{
summ=summ+1;
flag=1;
}
p=p->next;
}
if (flag==0)
{
printf("没有要统计的信息\n");
printf("%-10s%d",tempname,summ);
}
else
{
printf("%-10s%-0s\n","参赛项目","个数");
printf("%-10s%d\n",tempname,summ);
}
}
void countinformation()
{
int choice;
printf("*****************************************************\n");
printf("统计运动员性别:1 ;统计运动员所获名次信息: 2 ;统计学院所获名次信息: 3 ;统计参赛项目: 4 ;返回上一级:其他\n");
printf("*****************************************************\n");
scanf("%d",&choice);
if (choice==1)
{
countathlete();
}
else if (choice==2)
{
countscore();
}
else if (choice==3)
{
countcollege();
}
else if (choice==4)
{
countname();
}
}
五、代码分析
struct athleteData、struct matchData、struct scoreData定义运动员、比赛项目、参赛成绩的数据结构,后struct Linkathlete、struct Linkmatch、struct Linkscore定义运动员链表、比赛项目链表、参赛成绩链表的数据结构,以及下一个结点的指针。
函数creadathleteList()用于创建运动员链表,从文件"athlete.dat"中读取运动员数据,并将数据存储到链表中。
函数creadmatchList()用于创建比赛链表,从文件"match.dat"中读取比赛数据,并将数据存储到链表中。
函数creadscoreList()用于创建成绩链表,从文件"score.dat"中读取成绩数据,并将数据存储到链表中。
这段代码是用于从文件中读取数据并创建链表的函数,其作用是将文件中的数据读取出来,并创建一个包含这些数据的链表。
countcollege()函数用于统计学院所获名次信息。
我们调用creadscoreList()函数创建成绩链表,并将返回的链表头结点赋值给head。
接下来,通过用户输入获取要统计的学院名称。tempcollege用于存储用户输入的学院名称。
然后,使用while循环遍历链表,判断每个节点的学院名称是否与用户输入的学院名称相同。如果相同,则根据成绩的名次进行统计,并将flag标记为1。
最后,flag用于标记是否有要统计的信息。根据flag的值判断是否有要统计的信息。如果flag为0,则输出"没有要统计的信息";否则,输出学院名称以及第一名、第二名、第三名的人数。
countscore()函数用于统计运动员所获名次信息。
与countcollege()函数相似
countathlete()函数用于统计运动员性别信息。
调用creadathleteList()函数创建运动员信息链表,并将返回的链表头结点赋值给head。
后续用户输入要统计的性别,循环遍历,判断是否有相同性别,计数。
最后输出
countname()函数用于统计参赛项目信息。
与countathlete()函数相似
countinformation()函数用于提供统计功能的菜单选项。