#include <stdio.h> /*标准io库 */
#include <stdlib.h> /*定义杂项函数及内存分配函数的头文件 */
#include <string.h> /*字符串处理函数的头文件 */
#include <malloc.h> /*动态存储分配函数头文件 */
#define JUDEGNUM 3 /* 裁判数 */
#define NAMELEN 20 /* 姓名最大字符数 */
#define CODELEN 10 /* 号码最大字符数 */
#define FNAMELEN 80 /* 文件名最大字符数 */
#define BUFFSIZE 128 /* 缓冲区最大字符数 */
char judgement[JUDEGNUM][NAMELEN + 1] = { "judgementA", "judgementB", "judgementC" };
/*定义一个二维数组,用于存放裁判员的名字 */
/*定义一个结构体,用于存放运动员的比赛信息*/
struct AthleteScore {
char name[NAMELEN + 1]; /* 姓名 */
char code[CODELEN + 1]; /* 学号 */
int score[JUDEGNUM]; /* 各裁判给的成绩 */
int total; /* 总成绩 */
};
/*定义一个链表,用于存放各个运动员的比赛信息*/
struct LinkNode {
char name[NAMELEN + 1]; /* 姓名 */
char code[CODELEN + 1]; /* 号码 */
int score[JUDEGNUM]; /* 各裁判给的成绩 */
int total; /* 总成绩 */
struct LinkNode *next;
} *head; /* 链表首指针 */
int total[JUDEGNUM]; /* 各裁判给的总成绩 */
FILE *filepoint; /* 文件指针 */
char filename[FNAMELEN]; /* 文件名 */
/* 从指定文件读入一个记录 */
int GetRecord(FILE * fpt, struct AthleteScore *sturecord)
{
char buf[BUFFSIZE]; /*声明一个字符数组当作缓冲区,用于缓存读入的记录 */
int i; /*声明一个整型变量 */
if (fscanf(fpt, "%s", buf) != 1) /*判断把文件读入缓冲区的字符情况,如果读入的字符串长度不等于1,表示结 束;
如果等于1,则读入一条记录 */
return 0; /* 文件结束 */
strncpy(sturecord->name, buf, NAMELEN); /*把缓冲区的前20个字符复制给sturecord指向的结构体的姓名 */
fscanf(fpt, "%s", buf); /*将文件中的内容继续读入到缓冲区中 */
strncpy(sturecord->code, buf, CODELEN); /*把缓冲区中的10个字符复制给sturecord指向的结构体的学号 */
for (i = 0; i < JUDEGNUM; i++)
fscanf(fpt, "%d", &sturecord->score[i]); /*将文件中各个裁判给的成绩存放在一个数组中 */
for (sturecord->total = 0, i = 0; i < JUDEGNUM; i++) /*计算总成绩 */
sturecord->total += sturecord->score[i];
return 1;
}
/* 对指定文件写入一个记录 */
void PutRecord(FILE * fpt, struct AthleteScore *sturecord)
{
int i; /*声明一个整型变量 */
fprintf(fpt, "%s\n", sturecord->name); /*把sturecord指向的结构体的姓名输出到指定文件 */
fprintf(fpt, "%s\n", sturecord->code); /*把sturecord指向的结构体的学号输出到指定文件 */
for (i = 0; i < JUDEGNUM; i++) /*把各个裁判所给的成绩输出到指定文件中 */
fprintf(fpt, "%d\n", sturecord->score[i]);
return;
}
/* 显示运动员记录 */
void ShowAthleteRecord(struct AthleteScore *rpt)
{
int i; /*声明一个整型变量 */
printf("\nName : %s\n", rpt->name); /*打印出运动员的姓名 */
printf("Code : %s\n", rpt->code); /*打印出运动员的学号 */
printf("score :\n"); /*打印出运动员的各裁判员所给的成绩 */
for (i = 0; i < JUDEGNUM; i++)
printf(" %-15s : %4d\n", judgement[i], rpt->score[i]);
printf("Total : %4d\n", rpt->total); /*打印出总成绩 */
}
/* 列表显示运动员成绩 */
void Listathleteinfo(char *fname)
{
FILE *fp; /*声明一个文件指针 */
struct AthleteScore s; /*声明一个AthleteScore结构体 */
system("clear"); /*清屏 */
if ((fp = fopen(fname, "r")) == NULL) { /*只读打开文件,判断所读文件是否为空,如果不为空,显示运动员成绩 */
printf("Can't open file %s.\n", fname); /*文件若为空,则输出所读的文件不能打开 */
return; /*返回 */
}
while (GetRecord(fp, &s) != 0) { /*当所取的记录不为0,显示从 指定文件中读入的记录 */
ShowAthleteRecord(&s); /*调用显示运动员记录的函数 */
}
fclose(fp); /*关闭文件 */
return; /*返回 */
}
/* 构造链表 */
struct LinkNode *CreatLinklist(char *fname)
{
FILE *fp; /*声明一个文件指针 */
struct AthleteScore s; /*声明一个运动员得分的结构体 */
struct LinkNode *p, *u, *v, *h; /*声明链表结点 */
int i; /*声明一个整型变量 */
if ((fp = fopen(fname, "r")) == NULL) { /*只读打开文件,判断所读文件是否为空,如果不为空,则构造链表 */
printf("Can't open file %s.\n", fname); /*文件若为空,则输出所读的文件不能打开 */
return NULL; /*返回空 */
}
h = NULL; /*定义一个变量,并赋值为空 */
p = (struct LinkNode *)malloc(sizeof(struct LinkNode)); /*函数malloc分配一个类型为LikeNode的结点变量的空间,
并将其首地址放入指针变量p中 */
while (GetRecord(fp, (struct AthleteScore *)p) != 0) { /*指定文件写入的记录不为0时, */
v = h; /*将h赋值给v */
while (v && p->total <= v->total) { /*v为真并且p指向的总成绩小于等于v指向的总成绩 */
u = v; /*将v赋值给u */
v = v->next; /*v指向下一个结点 */
}
if (v == h) /*判断v是否等于h */
h = p; /*如果v等于h,则将p赋值给h */
else
u->next = p; /*如果v不等于h,则让u的下一个结点指向p */
p->next = v; /*p的下一个结点指向v */
p = (struct LinkNode *)malloc(sizeof(struct LinkNode)); /*函数malloc分配一个类型为LikeNode的结点变量的空间,
并将其首地址放入指针变量p中 */
}
free(p); /*释放p指向的空间 */
fclose(fp); /*关闭文件 */
return h; /*返回h */
}
/* 顺序显示链表各表元 */
void OutputLinklist(struct LinkNode *h)
{
system("clear"); /*清屏 */
while (h != NULL) { /*判断h指向的链表是否为空 */
ShowAthleteRecord((struct AthleteScore *)h); /*如果链表不为空,则调用函数 ShowAthleteRecord()来显示运动员记录 */
printf("\n"); /*换行 */
while (getchar() != '\n') ; /*当输入的字符不为换行时,h指向下一个结点 */
h = h->next;
}
return; /*返回 */
}
/* 按运动员姓名查找记录 */
int SearchbyName(char *fname, char *key)
{
FILE *fp; /*声明一个文件指针 */
int c; /*声明一个整型变量 */
struct AthleteScore s; /*声明一个指向运动员得分的结构体 */
system("clear"); /*清屏 */
if ((fp = fopen(fname, "r")) == NULL) { /*只读打开文件,判断所读文件是否为空 */
printf("Can't open file %s.\n", fname); /*文件若为空,则输出所读的文件不能打开 */
return 0; /*返回 */
}
c = 0; /*如果文件不为空,把c赋值为0 */
while (GetRecord(fp, &s) != 0) { /*当从指定文件写入的记录不为0时,则显示 */
if (strcmp(s.name, key) == 0) { /*让写入的记录的运动员的姓名与输入的运动员姓名进行比较 */
ShowAthleteRecord(&s); /*若相等,则显示运动员的记录 */
c++; /*c递增 */
}
}
fclose(fp); /*关闭文件 */
if (c == 0) /*判断c是否为0 */
printf("The athlete %s is not in the file %s.\n", key, fname); /*输出文件中不存在所输入姓名的运动员的记录 */
return 1; /*返回 */
}
/* 按运动员号码查找记录 */
int SearchbyCode(char *fname, char *key)
{
FILE *fp; /*声明一个文件指针 */
int c; /*声明一个整型变量 */
struct AthleteScore s; /*声明一个指向运动员得分的结构体 */
system("clear"); /*清屏 */
if ((fp = fopen(fname, "r")) == NULL) { /*只读打开文件,判断所读文件是否为空 */
printf("Can't open file %s.\n", fname); /*文件若为空,则输出所读的文件不能打开 */
return 0; /*返回 */
}
c = 0; /*如果文件不为空,把c赋值为0 */
while (GetRecord(fp, &s) != 0) { /*当从指定文件写入的记录不为0时,则显示 */
if (strcmp(s.code, key) == 0) { /*让写入的记录的运动员的学号与输入的运动员学号进行比较 */
ShowAthleteRecord(&s); /*若相等,则显示运动员的记录 */
c++; /*c递增 */
break; /*完成本次循环,跳出循环 */
}
}
fclose(fp); /*关闭文件 */
if (c == 0) /*判断c是否为0 */
printf("The athlete %s is not in the file %s.\n", key, fname); /*输出文件中不存在所输入姓名的运动员的记录 */
return 1; /*返回 */
}
/*向文件中输入运动员记录*/
void InsertRecord()
{
FILE *fp; /*声明一个文件指针 */
char c, i, j, n; /*声明字符变量 */
struct AthleteScore s; /*声明一个指向运动员得分的结构体 */
system("clear"); /*清屏 */
printf("请输入运动员得分记录的文件名: \n"); /*输出字符串 */
scanf("%s", filename); /*输入文件名 */
if ((fp = fopen(filename, "r")) == NULL) { /*只读打开文件,判断所读文件是否为空 */
printf("The file %s doesn't exit.\ndo you want to creat it? (Y/N) ", filename);
/*如果为空,则输出文件不存在,并询问是否要从新输入 */
getchar(); /*读入字符 */
c = getchar(); /*将读入的字符赋值给c */
if (c == 'Y' || c == 'y') { /*判断c是否等于Y或者是y */
fp = fopen(filename, "w"); /*如果相等,打开只写文件,若文件存在则文件长度清为0,
即该文件内容会消失。若文件不存在则建立该文件。 */
printf("请输入记录号 : "); /*输出 */
scanf("%d", &n); /*输入记录号 */
for (i = 0; i < n; i++) { /*做循环,输入运动员的记录 */
printf("请输入运动员的姓名: "); /*输出字符串 */
scanf("%s", &s.name); /*输入运动员的姓名 */
printf("请输入运动员的学号: "); /*输出字符串 */
scanf("%s", &s.code); /*输入运动员的学号 */
for (j = 0; j < JUDEGNUM; j++) { /*做循环,输入各个裁判的所打的分数 */
printf("请输入 %s 的分数: ", judgement[j]); /*输出字符串 */
scanf("%d", &s.score[j]); /*输入分数 */
}
PutRecord(fp, &s); /*调用函数,对指定文件写入记录 */
}
fclose(fp); /*关闭文件 */
}
}
fclose(fp); /*关闭文件 */
return; /*返回 */
}
int main()
{ /*主函数 */
int i, j, n; /*声明整型变量 */
char c; /*声明字符变量 */
char buf[BUFFSIZE]; /*定义字符数组作为缓冲区 */
while (1) {
system("clear"); /*清屏 */
printf("********************************************\n"); /*输出字符串 */
printf("*** 选择项 ****\n");
printf("*** 1:向文件插入一条记录. ****\n");
printf("*** 2:按运动员的姓名寻找记录. ****\n");
printf("*** 3:按运动员的号码寻找记录 . ****\n");
printf("*** 4:列出所有运动员记录. ****\n");
printf("*** 5:按总分从高到低排列显示. ****\n");
printf("*** 6:退出. ****\n");
printf("********************************************\n");
printf("请输入一个选择项的标号:\n");
scanf("%c", &c); /* 输入选择命令 */
switch (c) { /*做分支选择,对相应的输入号做相应的选择 */
case '1':
InsertRecord(); /*调用 InsertRecord(),向文件输入运动员的记录 */
getchar(); /*读入字符 */
break;
case '2': /* 按运动员的姓名寻找记录 */
printf("请输入所要查询的运动员的姓名:\n"); /*输出字符串 */
scanf("%s", buf); /*输入字符串并存放在缓冲区中 */
SearchbyName(filename, buf); /*调用SearchbyName(), 按运动员的姓名寻找记录 */
getchar(); /*读入字符 */
break;
case '3': /* 按运动员的学号寻找记录 */
printf("请输入所要查询的运动员的号码:\n"); /*输出字符串 */
scanf("%s", buf); /*输入字符串并存放在缓冲区中 */
SearchbyCode(filename, buf); /*调用SearchbyName(), 按运动员的学号寻找记录 */
getchar(); /*读入字符 */
break;
case '4': /* 列出所有运动员记录 */
Listathleteinfo(filename); /*调用Listathleteinfo(), 列出所有运动员记录 */
getchar();
break;
case '5': /* 按总分从高到低排列显示 */
if ((head = CreatLinklist(filename)) != NULL) /*判断构造的链表是否为空 */
OutputLinklist(head); /*若不为空,则调用OutputLinklist(),按总分从高到低排列显示 */
getchar();
break;
case '6':
return 1; /*返回 */
default:
break;
}
}
return 1; /*返回 */
}
请输入运动员得分记录的文件名:
/root/a.txtThe file /root/a.txt doesn't exit.
do you want to creat it? (Y/N) y
请输入记录号 : 1
请输入运动员的姓名: 张三
请输入运动员的学号: 001
请输入 judgementA 的分数: 78
请输入 judgementB 的分数: 89
请输入 judgementC 的分数: 88
段错误 (core dumped)