#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define M 10 // M个评委
struct player {
int num; // 歌手编号
char name[8]; // 歌手姓名
int score[M]; // M个评委的打分
};
#define BUFF_LEN 256 // 缓存区大小
#define NAME_MAX_LEN 8 // 姓名最大长度
#define PALYER_MAX_SIZE 128 // 最大歌手数量
struct player *player_list[PALYER_MAX_SIZE]; // 歌手列表 // 使用一个指针数组来保存所有的歌手信息
int player_num = 0; // 歌手数量
void addPlayer(int num, char *name) { // 添加歌手
int i;
player_list[player_num] = (struct player *)malloc(sizeof(struct player));
player_list[player_num]->num = num;
strcpy(player_list[player_num]->name, name);
for(i=0; i< M; i++) player_list[player_num]->score[i] = 0;
player_num++;
}
typedef int BOOL; // 自定义布尔类型
#define TRUE 1 // 真
#define FALSE 0 // 假
int readLine(char *buff) { // 从控制台读取一行
char c;
int i = 0;
while((c = getchar()) != '\n') {
if(i < BUFF_LEN - 1) {
buff[i] = c;
i++;
} else {
break;
}
}
buff[i] = '\0';
return i;
}
void readPlayerInfo(BOOL repeat) { // 从控制台读取歌手信息,其中,repeat是否重复录入
int i, num, len;
char buff[BUFF_LEN];
char *token;
printf("%s", "\n请输入歌手信息(含编号和姓名,使用空格隔开):");
while((len = readLine(buff)) != 0) {
token = strtok(buff, " "); // 提取编号
if((num = atoi(token)) == 0) {
printf("%s%s%s\n", "error: invalid id <", token, ">"); // 类型校验
goto end;
}
for(i=0; i< player_num; i++) {
if(num == player_list[i]->num) {
printf("%s%d%s\n", "error: is not unique <", num, ">"); // 唯一性校验
goto end;
}
}
token = strtok(NULL, " "); // 提取名称
if(token == NULL) {
printf("%s\n", "error: missing name");
goto end;
}
if(strlen(token) > NAME_MAX_LEN) {
printf("%s%s%s\n", "error: too long name <", token, ">"); // 长度校验
goto end;
}
// printf("%d,%s\n", num, token);
addPlayer(num, token);
printf("%s%d%s%d\n", "录入成功,当前歌手数量", player_num, "/", PALYER_MAX_SIZE);
if(repeat == FALSE) {
break;
}
end:
printf("%s", "\n请输入歌手信息:"); // 继续录入
}
}
int getScore(struct player *p, int *min, int *max) { // 计算平均成绩
int i, sum = 0;
*min = *max = -1;
for(i=0;i<M;i++) {
sum += p->score[i];
if(*min == -1 || *min > p->score[i])
*min = p->score[i];
if(*max == -1 || *max < p->score[i])
*max = p->score[i];
}
return (sum - *min - *max) / (M - 2);
}
int main(int argc, char **argv) { // 程序入口,其中:argc参数的个数,argv所有的参数
int i, j, len, num, ave, min, max;
char buff[BUFF_LEN];
struct player *temp;
BOOL found;
FILE *fp;
// 从文件加载歌手信息
if((fp=fopen("psr.dat","r"))!=NULL) {
while(!feof(fp)){
player_list[player_num] = (struct player *)malloc(sizeof(struct player));
if(fread(player_list[player_num], sizeof(struct player), 1, fp) == 1) {
player_num++;
}
}
fclose(fp);
printf("%d\n", player_num);
} else {
// 默认数据
addPlayer(1001, "张三");
addPlayer(1002, "李四");
addPlayer(1003, "王五");
}
for(;;) {
system("cls");
printf("%s\n", "***********************************歌手比赛系统********************************");
printf("%s\n", " 1.输入歌手信息");
printf("%s\n", " 2.评委打分");
printf("%s\n", " 3.成绩排序");
printf("%s\n", " 4.数据查询");
printf("%s\n", " 5.添加歌手");
printf("%s\n", " 6.写入数据文件");
printf("%s\n", " 7.退出系统");
printf("%s\n", "*******************************************************************************");
len = 0;
do {
if(len != 0) {
// printf("%s%s\n", "input: ", buff);
if(len == 1) {
switch(buff[0]) {
case '1' :
readPlayerInfo(TRUE);
break;
case '2' :
for(i=0; i< player_num; i++) {
for(j=0; j< M; j++) {
player_list[i]->score[j] = rand() % 101; // 随机分数,范围0-100
}
}
printf("%s\n", "打分结束");
break;
case '3' :
for(i=0; i< player_num -1 ; i++) { // 对歌手,按分数,进行冒泡排序
for(j=0; j< player_num - i - 1; j++) {
if (getScore(player_list[j], &min, &max) > getScore(player_list[j+1], &min, &max)) {
temp = player_list[j];
player_list[j] = player_list[j+1];
player_list[j+1] = temp;
}
}
}
printf(" %-5s%10s%10s%10s%10s%10s\n", "排名", "平均成绩", "编号", "姓名", "最低分", "最高分");
for(i=0; i< player_num; i++) { // 打印分数排名
ave = getScore(player_list[i], &min, &max);
printf(" %-5d%10d%10d%10s%10d%10d\n", i+1, ave, player_list[i]->num, player_list[i]->name, min, max);
}
break;
case '4' :
printf("%s\n", "请输入歌手编号:");
if((len = readLine(buff)) != 0) {
if((num = atoi(buff)) != 0) {
found = FALSE;
for(i=0; i< player_num; i++) {
if(num == player_list[i]->num) {
found = TRUE;
printf(" %-10s%10s\n", "编号", "姓名");
printf(" %-10d%10s%\n", player_list[i]->num, player_list[i]->name);
}
}
if(found == FALSE) {
printf("%s\n", "error: player not exists");
}
} else {
printf("%s%s%s\n", "error: invalid id <", buff, ">"); // 类型校验
}
}
break;
case '5' :
readPlayerInfo(FALSE);
break;
case '6' :
if((fp=fopen("psr.dat","w"))==NULL) {
printf("%s\n", "error: fail to open file");
exit(-1);
}
for(i=0; i< player_num; i++) {
fwrite(player_list[i], sizeof(struct player), 1, fp);
}
fclose(fp);
printf("%s\n", "写入成功");
break;
case '7' :
return 0; // 退出系统
break;
default:
printf("%s\n", "error: invalid operation");
}
} else {
printf("%s\n", "error: invalid operation");
}
}
printf("\n%s", "你想进行的操作:");
} while((len = readLine(buff)) != 0);
}
return 0;
}