需求:輸入 10 位學生的學號、姓名、三門課成績,計算平均分,存入二進制文件 stu.dat,並按平均分降序輸出排名(含學號、平均分、名次)。必須使用函數模塊化實現讀寫文件與排序。
#define MAX_STU 10
struct Student {
char id[12]; // 學號
char name[20]; // 姓名
int score[3]; // 三門成績
int avg; // 平均分(整數)
};
struct Student stu[MAX_STU + 1]; // 多留一個作為排序臨時交換空間
void input_students() {
for (int i = 0; i < MAX_STU; i++) {
printf("第 %d 位學生:\n", i+1);
printf(" 學號: "); scanf("%s", stu[i].id);
printf(" 姓名: "); scanf("%s", stu[i].name);
for (int j = 0; j < 3; j++) {
printf(" 成績 %d: ", j+1); scanf("%d", &stu[i].score[j]);
}
stu[i].avg = (stu[i].score[0] + stu[i].score[1] + stu[i].score[2]) / 3;
}
}
void save_to_file() {
FILE *fp = fopen("stu.dat", "wb");
if (!fp) { perror("無法創建文件"); return; }
for (int i = 0; i < MAX_STU; i++) {
if (fwrite(&stu[i], sizeof(struct Student), 1, fp) != 1)
fprintf(stderr, "寫入第 %d 筆失敗\n", i);
}
fclose(fp);
printf("數據已保存至 stu.dat\n");
}
void sort_by_avg_desc() {
for (int i = 0; i < MAX_STU - 1; i++) {
int max_idx = i;
for (int j = i + 1; j < MAX_STU; j++)
if (stu[j].avg > stu[max_idx].avg) max_idx = j;
if (max_idx != i) {
struct Student tmp = stu[i];
stu[i] = stu[max_idx];
stu[max_idx] = tmp;
}
}
}
void print_ranking() {
printf("\n%-5s %-12s %-10s %-10s %-10s %-8s %-6s\n",
"排名", "學號", "姓名", "成績1", "成績2", "成績3", "平均分");
for (int i = 0; i < MAX_STU; i++) {
printf("%-5d %-12s %-10s %-10d %-10d %-10d %-6d\n",
i+1, stu[i].id, stu[i].name,
stu[i].score[0], stu[i].score[1], stu[i].score[2], stu[i].avg);
}
}
int main() {
input_students();
save_to_file();
sort_by_avg_desc();
print_ranking();
return 0;
}
#include <stdio.h>
#include <string.h>
#define MAX_STU 10
struct Student {
char id[12];
char name[20];
int score[3];
int avg;
} stu[MAX_STU + 1];
void input_students() {
for (int i = 0; i < MAX_STU; i++) {
printf("請輸入第 %d 位學生的學號、姓名、三門成績:\n", i+1);
scanf("%s %s %d %d %d", stu[i].id, stu[i].name,
&stu[i].score[0], &stu[i].score[1], &stu[i].score[2]);
stu[i].avg = (stu[i].score[0] + stu[i].score[1] + stu[i].score[2]) / 3;
}
}
void save_to_file() {
FILE *fp = fopen("stu.dat", "wb");
if (!fp) { printf("文件打開失敗\n"); return; }
for (int i = 0; i < MAX_STU; i++)
fwrite(&stu[i], sizeof(struct Student), 1, fp);
fclose(fp);
printf("保存成功!\n");
}
void sort_by_avg_desc() {
for (int i = 0; i < MAX_STU - 1; i++) {
int k = i;
for (int j = i+1; j < MAX_STU; j++)
if (stu[j].avg > stu[k].avg) k = j;
if (k != i) {
struct Student t = stu[i];
stu[i] = stu[k];
stu[k] = t;
}
}
}
void print_ranking() {
printf("\n排名 學號 姓名 成績1 成績2 成績3 平均分\n");
for (int i = 0; i < MAX_STU; i++)
printf("%-5d %-12s %-10s %-6d %-6d %-6d %-6d\n",
i+1, stu[i].id, stu[i].name,
stu[i].score[0], stu[i].score[1], stu[i].score[2], stu[i].avg);
}
int main() {
input_students();
save_to_file();
sort_by_avg_desc();
print_ranking();
return 0;
}
fwrite/fread 直接操作內存塊,高效簡單,但跨平台需注意結構體對齊與字節序。qsort(需編寫比較函數)。printf 格式字符串控制列對齊,提升可讀性。scanf("%s", &stu[i].id) 錯誤:數組名本身是地址,不要加 &。for(i=0; i<MAX_STU; i++) 而非 i<=MAX_STU。tmp = stu[i]),而非逐字段複製。fclose。