用二进制文件格式完成任务: 班上有30人,每人有学号,数学,英语,c语言3门课程的成绩数据。编程完成如下任务: 1、将数据输入到文本文件score.txt 2、计算每人总分,将学号,数学,英语,c语言,总分等数据按总分从高到低输出每位同学的全部数据。 3、将每位同学的数据按学号顺序计算输出各同学的总分排名,分数最高的名次为1,分数相同的名次相同,若有i个同学排在第x位,则下个分数的名次为x+i位。并将这些数据均写入文本文件newscore.txt
时间: 2023-05-28 13:07:37 浏览: 137
由于题目要求使用二进制文件格式完成任务,因此需要使用二进制文件读写相关的函数。
以下是使用C语言完成题目的代码:
```c
#include <stdio.h>
#include <stdlib.h>
// 定义学生结构体
typedef struct {
int id;
int math;
int english;
int c;
int sum;
} Student;
// 读取学生数据
void read_student_data(Student *student, FILE *fp) {
fread(&(student->id), sizeof(int), 1, fp);
fread(&(student->math), sizeof(int), 1, fp);
fread(&(student->english), sizeof(int), 1, fp);
fread(&(student->c), sizeof(int), 1, fp);
student->sum = student->math + student->english + student->c;
}
// 写入学生数据
void write_student_data(Student *student, FILE *fp) {
fwrite(&(student->id), sizeof(int), 1, fp);
fwrite(&(student->math), sizeof(int), 1, fp);
fwrite(&(student->english), sizeof(int), 1, fp);
fwrite(&(student->c), sizeof(int), 1, fp);
fwrite(&(student->sum), sizeof(int), 1, fp);
}
// 比较函数,用于排序
int compare(const void *a, const void *b) {
const Student *s1 = (const Student *)a;
const Student *s2 = (const Student *)b;
if (s1->sum > s2->sum) {
return -1;
} else if (s1->sum < s2->sum) {
return 1;
} else {
return s1->id - s2->id;
}
}
int main() {
// 打开输入文件
FILE *fp_in = fopen("score.txt", "rb");
if (fp_in == NULL) {
perror("score.txt");
return EXIT_FAILURE;
}
// 读取学生数据
Student students[30];
for (int i = 0; i < 30; i++) {
read_student_data(&(students[i]), fp_in);
}
// 关闭输入文件
fclose(fp_in);
// 按总分从高到低排序
qsort(students, 30, sizeof(Student), compare);
// 打开输出文件
FILE *fp_out = fopen("newscore.txt", "wb");
if (fp_out == NULL) {
perror("newscore.txt");
return EXIT_FAILURE;
}
// 输出每位同学的全部数据
for (int i = 0; i < 30; i++) {
printf("%d %d %d %d %d\n", students[i].id, students[i].math, students[i].english, students[i].c, students[i].sum);
write_student_data(&(students[i]), fp_out);
}
// 关闭输出文件
fclose(fp_out);
// 按学号顺序计算输出各同学的总分排名
int rank[30] = {0};
for (int i = 0; i < 30; i++) {
int count = 1;
for (int j = 0; j < 30; j++) {
if (students[j].sum > students[i].sum || (students[j].sum == students[i].sum && students[j].id < students[i].id)) {
count++;
}
}
rank[students[i].id - 1] = count;
}
// 输出每位同学的总分排名
for (int i = 0; i < 30; i++) {
printf("%d %d\n", i + 1, rank[i]);
}
return 0;
}
```
在程序中,我们首先定义了一个学生结构体,其中包括学号、数学、英语、c语言和总分五个成员变量。
然后我们定义了三个函数,分别用于读取学生数据、写入学生数据和比较函数(用于排序)。
在 `main` 函数中,我们首先打开输入文件 `score.txt`,然后使用二进制文件读取相关的函数读取学生数据,并存储到数组 `students` 中。
然后我们对数组 `students` 进行排序,排序的关键字是总分从高到低,若总分相同则按学号从小到大排序。这里使用了标准库函数 `qsort`。
接着,我们打开输出文件 `newscore.txt`,并按总分从高到低输出每位同学的全部数据。同时,我们使用计数排序的思想,按学号顺序计算输出各同学的总分排名,并存储到数组 `rank` 中。
最后,我们输出每位同学的总分排名。
注意,我们在读写二进制文件时,使用的是 `fread` 和 `fwrite` 函数,而不是 `fscanf` 和 `fprintf` 函数。因为二进制文件不包含换行符等特殊字符,使用 `fscanf` 和 `fprintf` 函数可能会出现问题。
阅读全文