本文为数据结构与算法的课程设计《运动会分数统计》的一个分享,使用了顺序表的数据结构。并且将信息以表格的方式打印输出和在txt文件中导入导出。
目录
1.设计内容和要求
设计内容: 有n个学校参加运动会,学校名对应的编号为1……n。比赛分成m个男子项目,和w个女子项目。每个项目取前三名积分,前三名的积分分别为:5、3、2;数据可以存储在一个数据文件中,数据结构、具体数据自定。 具体功能有: (1)从键盘输入学校、项目、项目得分信息; (2)能统计各学校总分; (3)能统计各个项目的前三名; (4)可以按学校编号或名称、学校总分、男女团体总分排序输出; (5)可以按学校编号查询学校某个项目的情况; (6)可以按项目编号查询取得前三名的学校。 (7)数据存入文件并能随时查询。 设计要求: 1.符合课题要求,实现相应功能; 2.要求界面友好美观,操作方便易行; 3. 注意程序的实用性、安全性; |
2.代码实现
1.结构体定义
typedef struct eve {
int score = 0; //项目成绩
int point = 0; //项目得分
}event;
typedef struct school {
int id = 0; //学校编号
char name[length_2]; //学校名称
event Man_event_point[m]; //男子项目得分
event Woman_event_point[w]; //女子项目得分
int Man_total_point = 0; //男子项目总得分
int Woman_total_point = 0; //女子项目总得分
int Points = 0; //学校总得分
}School[n], school;
结构体涵盖了课题中的信息,对于男子项目和女子项目另外设置了一个event的结构体。
2.全局变量和变量定义
#define n 8 //学校数量
#define m 5 //男子项目数量
#define w 5 //女子项目数量
#define MAX_FILENAME_LENGTH 50
#define MAX_NAME_LENGTH 100
#define length_1 15
#define length_2 20
#define length_3 21
#define length_4 21
#define length_5 10
School S; //全局变量
int rank_Man[m][3]; //用于存储每个项目前三名的学校编号
int rank_Woman[w][3];
将存储数据的数组S定义为全局变量,主要目的是为了避免后续函数使用时进行传参。rank这是两个二维数组是为了实现可以按项目编号查询取得前三名的学校。以rank_Man为例,每一行表示一个项目,后三列每一列都存储一个编号来表示第一,二,三名。例如:rank_Man[1][2]表示男子第二个项目的第一名。length 1-5是设定的打印表格的宽度。
3.键盘输入信息
void Add_school() {
printf("开始输入学校信息,共%d所学校\n", n);
for (int i = 0; i < n; i++) {
printf("*****************\n");
printf("第%d所学校\n", i+1);
printf("请输入学校编号\n");
scanf("%d", & S[i].id);
printf("请输入学校名称\n");
scanf("%s", (S[i].name));
printf("下面开始输入男子项目得分,共%d项\n", m);
for (int j = 0; j < m; j++) {
printf("男子第%d个项目得分:", j+1);
scanf("%d", &((S[i].Man_event_point[j]).score));
}
printf("\n");
printf("下面开始输入女子项目得分,共%d项\n", w);
for (int j = 0; j < w; j++) {
printf("女子第%d个项目得分:", j+1);
scanf("%d", &((S[i].Woman_event_point[j]).score));
}
}
printf("信息已全部输入完成\n\n");
}
信息输入部分很常规,学校数量n,男子项目数量m,女子项目数量w都已经提供,for循环键入即可。
4.信息显示
void P_total() {
printf("┌───────────────┬────────────────────┬─────────────────────┬─────────────────────┬─────────────────────┐\n");
printf("│ 编号 │ 学校 │ 男子项目总分 │ 女子项目总分 │ 学校总分 │\n");
printf("├───────────────┼────────────────────┼─────────────────────┼─────────────────────┼─────────────────────┤\n");
for (int i = 0; i < n; i++) {
printf("│");
int padding = (length_1 - 1) / 2; for (int i = 0; i < padding; i++) { printf(" "); } if (S[i].id > 9) { padding++; if (S[i].id > 99) { padding++; }}
printf("%d",S[i].id); for (int i = 0; i < length_1 - 1 - padding; i++) { printf(" "); } //首先尝试默认一位后续补齐
printf("│");
int padd = (length_2 + 1 - strlen(S[i].name)) / 2; for (int k = 0; k < padd; k++) { printf(" "); }
printf("%s",S[i].name); for (int j = 0; j < (length_2 - padd -strlen(S[i].name));j++) { printf(" "); }
printf("│");
padding = (length_3 - 1) / 2; for (int i = 0; i < padding; i++) { printf(" "); } if (S[i].Man_total_point > 9) { padding++; if (S[i].Man_total_point > 99) { padding++; }}
printf("%d",S[i].Man_total_point); for (int i = 0; i < length_3 - 1 - padding; i++) { printf(" "); }
printf("│");
padding = (length_3 - 1) / 2; for (int i = 0; i < padding; i++) { printf(" "); } if (S[i].Woman_total_point > 9) { padding++; if (S[i].Woman_total_point > 99) { padding++; }}
printf("%d",S[i].Woman_total_point); for (int i = 0; i < length_3 - 1 - padding; i++) { printf(" "); }
printf("│");
padding = (length_4 - 1) / 2; for (int i = 0; i < padding; i++) { printf(" "); } if (S[i].Points > 9) { padding++; if (S[i].Points > 99) { padding++; }}
printf("%d",S[i].Points); for (int i = 0; i < length_4 - 1 - padding; i++) { printf(" "); }printf("│");
printf("\n");
if (i + 1 < n) {
printf("├───────────────┼────────────────────┼─────────────────────┼─────────────────────┼─────────────────────┤\n");
}
else {
printf("└───────────────┴────────────────────┴─────────────────────┴─────────────────────┴─────────────────────┘\n");
}
}
}
void P_event() {
int length_M = length_5 * m;
int length_W = length_5 * w;
printf("┌───────────────┬────────────────────┬"); for (int i = 0; i < (length_M + m-1); i++) { printf("─"); }printf("┬"); for (int i = 0; i < (length_W + w-1); i++) { printf("─"); } printf("┐\n");
printf("│ │ │");int padding = (length_M+1 - 7) / 2; for (int i = 0; i < padding; i++) { printf(" "); }printf("男子项目"); for (int i = 0; i < length_M+1 - 8 - padding; i++) { printf(" "); } printf("│"); padding = (length_W+1 - 8) / 2; for (int i = 0; i < padding; i++) { printf(" "); }printf("女子项目"); for (int i = 0; i < length_W+1 - 8 - padding; i++) { printf(" "); } printf("│\n");
printf("│ 编号 │ 学校 ├"); //汉字占用两个字节
for (int i = 0; i < m + w; i++) {
for (int i = 0; i < length_5; i++) { printf("─"); }
if (i == w + m - 1) { printf("┤\n"); }
else if (i == m - 1) { printf("┼"); }
else { printf("┬"); }
}
printf("│ │ "); for (int i = 0; i < m; i++) { printf("│"); padding = (length_5 - 1) / 2; for (int i = 0; i < padding; i++) { printf(" "); } if (i > 9) { padding++; if (i > 99) { padding++; } } printf("%d", i+1); for (int i = 0; i < length_5 - 1 - padding; i++) { printf(" "); } }for (int i = 0; i < w; i++) {
printf("│"); padding = (length_5 - 1) / 2; for (int i = 0; i < padding; i++) { printf(" "); } if (i > 9) { padding++; if (i > 99) { padding++; } }
printf("%d", i+1); for (int i = 0; i < length_5 - 1 - padding; i++) { printf(" "); }}printf("│\n");//首先尝试默认一位后续补齐 }
printf("├───────────────┼────────────────────"); for (int i = 0; i < m + w; i++) { printf("┼"); for (int i = 0; i < length_5; i++) { printf("─"); } }printf("┤\n");
for (int i = 0; i < n; i++) {
printf("│");
int padding = (length_1 - 1) / 2; for (int i = 0; i < padding; i++) { printf(" "); } if (S[i].id > 9) { padding++; if (S[i].id > 99) { padding++; } }
printf("%d", S[i].id); for (int i = 0; i < length_1 - 1 - padding; i++) { printf(" "); } //首先尝试默认一位后续补齐
printf("│");
int padd = (length_2 + 1 - strlen(S[i].name)) / 2; for (int k = 0; k < padd; k++) { printf(" "); }
printf("%s", S[i].name); for (int j = 0; j < (length_2 - padd - strlen(S[i].name)); j++) { printf(" "); }
for (int j = 0; j < m; j++) { printf("│");
padding = (length_5 - 1) / 2;
for (int i = 0; i < padding; i++) { printf(" "); } if (S[i].Man_event_point[j].score > 9) { padding++; if (i > 99) { padding++; } }
printf("%d", S[i].Man_event_point[j].score);
for (int i = 0; i < length_5 - 1 - padding; i++) { printf(" "); }}
for (int j = 0; j < w; j++) { printf("│");
padding = (length_5 - 1) / 2; for (int i = 0; i < padding; i++) { printf(" "); } if (S[i].Woman_event_point[j].score > 9) { padding++; if (i > 99) { padding++; } }
printf("%d", S[i].Woman_event_point[j].score);
for (int i = 0; i < length_5 - 1 - padding; i++) { printf(" "); }}
printf("│\n");//首先尝试默认一位后续补齐 最多去比较到三位数
if(i+1<n){ printf("├───────────────┼────────────────────"); for (int i = 0; i < m + w; i++) { printf("┼"); for (int i = 0; i < length_5; i++) { printf("─"); } }printf("┤\n"); }
else { printf("└───────────────┴────────────────────"); for (int i = 0; i < m + w; i++) { printf("┴"); for (int i = 0; i < length_5; i++) { printf("─"); } }printf("┘\n"); }
}
}
这里设置了两种数组显示模式,一种是P_total,按照团队总分和总得分进行输出,另一种是P_event,按照每一项项目的成绩进行输出。
为了能以表格的形式输出数据,我使用了“┌”,“─”,“┬”,“┐”,“├”,“┼” ,“┤”,“└”,“┴”,“┘”等制表符和空格来绘制,为了使数据能居中输出,使用padding变量来计算:字符型可以直接使用strlen来计算控制长度,对于整形,我加入了一个判断条件,如果大于9,数据后的空格减一,如果大于99,数据后的空格再减一。(不会计算int型的长度,只能出此下计)。另外,至于表头中需要打印汉字,特意计算了一下,一个汉字是占用两个字节的。这样,再配合printf固定输入的表头表尾,就能绘制出一个美观的表格了。(实际代码写的很冗长,好多循环变量重复使用,代码阅读很不方便,应当优化。)
5.文件导入导出信息
这是保存到文件中的样子。
void Writefile() {
getchar();
char filename[50];
printf("请输入导出文件的名称(不含扩展名): ");
// 使用 fgets 代替 scanf_s 以避免缓冲区溢出,并允许空格
if (fgets(filename, sizeof(filename), stdin) != NULL) {
// 移除 fgets 读取的换行符(如果有)
size_t len = strlen(filename);
if (len > 0 && filename[len - 1] == '\n') {
filename[len - 1] = '\0';
}
// 确保有足够的空间添加扩展名
if (strlen(filename) + 4 < sizeof(filename)) { // 4 是 ".txt" 的长度加上空字符
strcat(filename, ".txt"); // 自动添加扩展名
FILE* file = fopen(filename, "w");
if (file == NULL) {
printf("无法打开文件 %s !\a\n", filename);
return;
}
// 写入数据
int length_M = length_5 * m;
int length_W = length_5 * w;
fprintf(file, "┌───────────────┬────────────────────┬"); for (int i = 0; i < (length_M + m - 1); i++) { fprintf(file, "─"); }fprintf(file, "┬"); for (int i = 0; i < (length_W + w - 1); i++) { fprintf(file, "─"); } fprintf(file, "┐\n");
fprintf(file, "│ │ │"); int padding = (length_M + 1 - 7) / 2; for (int i = 0; i < padding; i++) { fprintf(file, " "); }fprintf(file, "男子项目"); for (int i = 0; i < length_M + 1 - 8 - padding; i++) { fprintf(file, " "); } fprintf(file, "│"); padding = (length_W + 1 - 8) / 2; for (int i = 0; i < padding; i++) { fprintf(file, " "); }fprintf(file, "女子项目"); for (int i = 0; i < length_W + 1 - 8 - padding; i++) { fprintf(file, " "); } fprintf(file, "│\n");
fprintf(file, "│ 编号 │ 学校 ├"); //汉字占用两个字节
for (int i = 0; i < m + w; i++) {
for (int i = 0; i < length_5; i++) { fprintf(file, "─"); }
if (i == w + m - 1) { fprintf(file, "┤\n"); }
else if (i == m - 1) { fprintf(file, "┼"); }
else { fprintf(file, "┬"); }
}
fprintf(file, "│ │ "); for (int i = 0; i < m; i++) { fprintf(file, "│"); padding = (length_5 - 1) / 2; for (int i = 0; i < padding; i++) { fprintf(file, " "); } if (i > 9) { padding++; if (i > 99) { padding++; } } fprintf(file, "%d", i + 1); for (int i = 0; i < length_5 - 1 - padding; i++) { fprintf(file, " "); } }for (int i = 0; i < w; i++) {
fprintf(file, "│"); padding = (length_5 - 1) / 2; for (int i = 0; i < padding; i++) { fprintf(file, " "); } if (i > 9) { padding++; if (i > 99) { padding++; } }
fprintf(file, "%d", i + 1); for (int i = 0; i < length_5 - 1 - padding; i++) { fprintf(file, " "); }
}fprintf(file, "│\n");//首先尝试默认一位后续补齐 }
fprintf(file, "├───────────────┼────────────────────"); for (int i = 0; i < m + w; i++) { fprintf(file, "┼"); for (int i = 0; i < length_5; i++) { fprintf(file, "─"); } }fprintf(file, "┤\n");
for (int i = 0; i < n; i++) {
fprintf(file, "│");
int padding = (length_1 - 1) / 2; for (int i = 0; i < padding; i++) { fprintf(file, " "); } if (S[i].id > 9) { padding++; if (S[i].id > 99) { padding++; } }
fprintf(file, "%d", S[i].id); for (int i = 0; i < length_1 - 1 - padding; i++) { fprintf(file, " "); } //首先尝试默认一位后续补齐
fprintf(file, "│");
int padd = (length_2 + 1 - strlen(S[i].name)) / 2; for (int k = 0; k < padd; k++) { fprintf(file, " "); }
fprintf(file, "%s", S[i].name); for (int j = 0; j < (length_2 - padd - strlen(S[i].name)); j++) { fprintf(file, " "); }
for (int j = 0; j < m; j++) {
fprintf(file, "│");
padding = (length_5 - 1) / 2;
for (int i = 0; i < padding; i++) { fprintf(file, " "); } if (S[i].Man_event_point[j].score > 9) { padding++; if (i > 99) { padding++; } }
fprintf(file, "%d", S[i].Man_event_point[j].score);
for (int i = 0; i < length_5 - 1 - padding; i++) { fprintf(file, " "); }
}
for (int j = 0; j < w; j++) {
fprintf(file, "│");
padding = (length_5 - 1) / 2; for (int i = 0; i < padding; i++) { fprintf(file, " "); } if (S[i].Woman_event_point[j].score > 9) { padding++; if (i > 99) { padding++; } }
fprintf(file, "%d", S[i].Woman_event_point[j].score);
for (int i = 0; i < length_5 - 1 - padding; i++) { fprintf(file, " "); }
}
fprintf(file, "│\n");//首先尝试默认一位后续补齐 最多去比较到三位数
if (i + 1 < n) { fprintf(file, "├───────────────┼────────────────────"); for (int i = 0; i < m + w; i++) { fprintf(file, "┼"); for (int i = 0; i < length_5; i++) { fprintf(file, "─"); } }fprintf(file, "┤\n"); }
else { fprintf(file, "└───────────────┴────────────────────"); for (int i = 0; i < m + w; i++) { fprintf(file, "┴"); for (int i = 0; i < length_5; i++) { fprintf(file, "─"); } }fprintf(file, "┘\n"); }
fprintf(file,"\n\n");
fprintf(file, "┌───────────────┬────────────────────┬─────────────────────┬─────────────────────┬─────────────────────┐\n");
fprintf(file, "│ 编号 │ 学校 │ 男子项目总分 │ 女子项目总分 │ 学校总分 │\n");
fprintf(file, "├───────────────┼────────────────────┼─────────────────────┼─────────────────────┼─────────────────────┤\n");
for (int i = 0; i < n; i++) {
fprintf(file, "│");
int padding = (length_1 - 1) / 2; for (int i = 0; i < padding; i++) { fprintf(file, " "); } if (S[i].id > 9) { padding++; if (S[i].id > 99) { padding++; } }
fprintf(file, "%d", S[i].id); for (int i = 0; i < length_1 - 1 - padding; i++) { fprintf(file, " "); } //首先尝试默认一位后续补齐
fprintf(file, "│");
int padd = (length_2 + 1 - strlen(S[i