一、题目要求
1.题目描述
从100名优秀运动员中评选出10名最佳运动员。具体规则如下。
(1)运动员号按1、2、3…..顺序编号;
(2)由键盘接受所收到的选票,每张选票至多可写10个不同的编号;
(3)对应名次的运动员编号可以有空缺,但必须用0表示;
(4)若编号超出规定的范围,或编号出现重复,作废选票;
(5)按选票中所列最佳运动员顺序给他们计分,计分标准如下:从第1名至第10名所得分数依次为:15,12,9,7,6,5,4,3,2,1;
(6)按各运动员所得分数高低进行排队,列出前十名最佳运动员排名,格式为:
名次 运动员编号 合计得分 合计得票数
如果得分相同,则得票多者在前,如果得分与票数都相同,则编号小的在前。
要求每个功能模块用一个函数实现。
2.设计提示
(1)评选过程分为3个步骤:输入选票、读取选票及选票检查(即看是否为废票)、有效票统计。
(2)程序功能由4个函数完成。
Main()主函数:调用input()函数输入选票,再调用check()函数进行废票检查,调用count()函数进行统计得分与排名,最后输出总选票数、有效票数和前十名运动员的排行榜。
input()函数:将所有选票全部录入到文件vote.txt中,可以用运动员编号为 -1来标识每张选票的结束。
check()函数: 从文件vote.txt中读取选票信息,对每张选票进行检查,看是否有效,对出现编号重复或编号超出范围则作废处理,不予登记;
count()函数:统计总选票数和有效票的数量;统计每个运动员的总得票数和总分,然后排出名次;
二、源代码
/*******************************************************************
************************************
> File Name:选票系统.c
> Author:xlj
> Mail:932834897@qq.com
> Created Time:~~
************************************
*******************************************************************/
#include<stdio.h>
#include<stdlib.h> //system。。。
#include<windows.h> //Sleep函数
#define N 100 //有100个同学
#define zifu0 " ********* \n "
#define zifu1 "**************************************************\n"
#define zifu2 "| 名次 | 学生编号 | 合计得分 | 合计得票数 |\n"
#define zifu3 "***********************************************\n"
#define zifu4 " ********* \n"
#define zifu5 " 请选择你的操作【1-3】\n\n"
#define zifu6 " ***** \n"
#define zifu7 " ********* \n\n"
#define zifu8 " ********* \n"
#define zifu9 " ***** \n"
#define zifu10 " 1.打开输入表格\n\n"
#define zifu11 " 2.打开显示结果\n\n"
#define zifu12 " 3.退出 \n\n"
#define zifu13 " *******选票已完毕********\n"
#define zifu14 " 请您输入“2”来打开最后选票结果\n"
int check(void); //检验选票
void conut(int ,int); //统计选票
void input(int ); //输入函数
int abandon=0;//废票的判断变量
int tun=0;//废票的判断变量
struct student
{
int score;//学生得分
int vote;//学生得票
int n;//学生编号
};
struct student number[100];//存放100个学生的结构体数组
int vote[10]={0}; //投票存放数组
int main()
{
int i=0;
int j=0; //j从0-9代表每张选票分别对应每个学生
int f=0; //f接收check函数返回的值
int k=0; //k控制投票的循环,若投票过程中输入-1,k将会=1,然后投票终止
int p=0; //p控制请稍等...的for循环
int q=0; //q接收输入的值,来操作是否进行下一步
int count=1; //计数器 ,计几张选票
int tally=1; //计数器 ,计选票里几个号
system("color 70");
printf(zifu5);
printf(zifu6);
printf(zifu7);
printf(zifu10);
printf(zifu11);
printf(zifu12);
printf(zifu8);
printf(zifu9);
while(scanf("%d",&q))
{
if(1==q)
{
system("cls");//清屏
system("color 70"); //改变颜色
printf("正在尝试打开输入表格,稍等....");
for(p=1;p<=100;p++)
{
printf("%3d",p);
printf("%%");//C语言的要求,输出两个%才可以输出%
Sleep(50);
printf("\b\b\b\b");//\b的意思是使光标移动
}
for(i=1;i<=100;i++) //学生编号赋值
number[i-1].n=i;
for(k=0;k!=1;) //投票循环
{
printf ("\n\n\n请你在第%d张选票里选[0~100]号码\n",count);
for(j=0,tally=1;j<=9;j++,tally++)
{
printf("%d号:",tally);
input(j);
if(-1==vote[j])
{
k=1;
break;
} //接收到"-1"则停止接受投票
}
count++;
f=check(); //调用检验选票函数返回控制变量"f"
conut(k,f); //调用统计选票函数
if(0==abandon||2==tun)
{
printf("\n\n废票");
k=0;
continue;
}
}
if(1==k)//因为前面k=1跳出for循环,但还没有跳出while循环,所以需要这里
{
break;
}
}
else if(2==q)
{
printf("还没有选票,无法显示选票结果\n");
}
else if(3==q)
{
return;
}
else
{
printf("请输入【1-3】!");
}
}
printf(zifu13);
printf(zifu14);
while(scanf("%d",&q))
{
if(2==q)
{
system("cls");//清屏
printf("正在尝试打开统计结果,稍等....");
for(p=1;p<=100;p++)
{
printf("%3d",p);
printf("%%");//C语言的要求,输出两个%才可以输出%
Sleep(50);
printf("\b\b\b\b");//\b的意思是使光标移动
}
printf("\n统计结果揭晓:\n"); //投票结果输出
printf(zifu0);
printf(zifu1);
printf(zifu2);
for(i=0;i<=9;i++)
{
printf("%5d%10d%13d%13d\n",i+1,number[i].n,number[i].score,number[i].vote);
}
printf(zifu3);
printf(zifu4);
printf("\n恭喜以上10位同学拔得头筹!!!");
}
else
{
printf("请重新输入,并输入“2”\n");
}
}
return 0;
}
void input(int j)
{
FILE *fp;
if((fp=fopen("d:\\vote.txt","a"))==NULL)//追加数据用a
{
printf("open error!");
exit(1);
}
scanf("%d",&vote[j]);
fprintf(fp,"%d",vote[j]);
fclose(fp);
}
int check() //检验选票函数
{
int i,j;
tun=0;
for(i=0;i<=9;i++)
{
if(vote[i]==-1)//假如输入-1,直接退出此函数且返回1,这里为什么要写,因为输入-1后其他值默认为0.后面的if会进入,那么tun就会改变了
{
return 1;
}
for(j=i+1;j<=9;j++)
{
if(vote[i]==vote[j]) //相同票则为废票返回1
{
tun=2;
return 1;
}
}
if(vote[i]>100||vote[i]<-1||vote[i]==0) //超出范围票作废票返回1
{
tun=2;
return 1;
}
}
abandon++;
return 0; //不是废票则返回0
}
void conut(int x,int y) //统计选票函数函数
{
int i;//i控制每张选票里10个号码的循环,还有冒泡中的前一位
int j;//j用于冒泡排序中的后一位
int t;//排序中间变量
int k;//接收每张选票里的号码
if(0==y) //根据检验选票函数返回值决定此票是否需要计入,这里检验的是一张选票
{
for(i=0;i<10;i++)
{
k=vote[i];
if(0==vote[i])
{
continue;
}
else //如果不是废票则计入
{
number[k-1].vote++; //票数加1,k-1代表数组是从0开始的
switch(i+1)
{
case 1: number[k-1].score=number[k-1].score+15; break; //按照选票次序得分加上相应分
case 2: number[k-1].score=number[k-1].score+12; break;
case 3: number[k-1].score=number[k-1].score+9; break;
case 4: number[k-1].score=number[k-1].score+7; break;
case 5: number[k-1].score=number[k-1].score+6; break;
case 6: number[k-1].score=number[k-1].score+5; break;
case 7: number[k-1].score=number[k-1].score+4; break;
case 8: number[k-1].score=number[k-1].score+3; break;
case 9: number[k-1].score=number[k-1].score+2; break;
case 10: number[k-1].score=number[k-1].score+1; break;
}
}
}
}
if(x==1) //根据投票结束控制变量决定是否需要给结果进行排序
{
for(j=0;j<10;j++) //进行排序
for(i=j+1;i<100;i++)
{
if(number[j].score<number[i].score) //得分高者在前
{
t=number[j].vote; //交换学生票数
number[j].vote=number[i].vote;
number[i].vote=t;
t=number[j].score; //交换学生分数
number[j].score=number[i].score;
number[i].score=t;
t=number[j].n; //交换学生编号
number[j].n=number[i].n;
number[i].n=t;
}
else if(number[j].score==number[i].score)//若得分相同则比较其他信息
{
if(number[j].vote<number[i].vote) //得分相同票多在前
{
t=number[j].vote; //交换学生票数
number[j].vote=number[i].vote;
number[i].vote=t;
t=number[j].score; //交换学生分数
number[j].score=number[i].score;
number[i].score=t;
t=number[j].n; //交换学生编号
number[j].n=number[i].n;
number[i].n=t;
}
}
else if(number[j].score==number[i].score&&number[j].vote==number[i].vote)
{
if(number[j].n<number[i].n)
{
if(number[j].vote<number[i].vote) //得分相同票多在前
{
t=number[j].vote; //交换学生票数
number[j].vote=number[i].vote;
number[i].vote=t;
t=number[j].score; //交换学生分数
number[j].score=number[i].score;
number[i].score=t;
t=number[j].n; //交换学生编号
number[j].n=number[i].n;
number[i].n=t;
}
}
}
}
}
}
三、效果图
*注:未经同意,该篇不得转载