c语言 文件读取与数据排序

score.txt 是100名学生的成绩数据,每行数据从左至右是学号、英语分数、数学分数和语文分数,用空格隔开。
创建一个程序来输出三个科目成绩总分为 n 位的学号,该生的总分和三个科目成绩中的最低分,用空格隔开。
但是,如果总分相同,则将三门课程分数中最低分较高的学生名次排高; 如果最低分也相同,则将学号较小的学生排高。在编写程序时,我们只需要利用 score.txt 中描述的学生人数为100人,并编写代码,只有当学生人数为100人时才能正常工作。另外,score.txt 应与执行代码的目录位于同一目录中。

毫无头绪,想问一下应该怎么写,如果能有步骤讲解就更好了,谢谢。

下面是我理解的一个思路,供参考:
1、先定义一个学生结构,含有三个结构成员:学号,英语分数,数学分数,语文分数,总分。
2、然后用fscanf函数从score.txt读取100个学生的学号,分数信息到学生结构数组里面,并在读取时计算总分
3、用冒泡排序或选择排序,把这个学生结构数组按三科成绩的总分排序
4、从输入获取需要查询的n位学生的n
5、然后用一个for循环遍历按排序后的结构数组,寻找第n位学生的信息,然后打印结果。
我用3个学生的信息进行了测试,截图是在实际程序自动生成的100个学生数据进行的测试结果。
参考链接:
【c语言】求三个数的最小数_折腾的小飞的博客-CSDN博客_c语言三个数求最小值
https://jingyan.baidu.com/article/a378c9608fd37df2282830db.html
fscanf读入文件时错误的原因?_善良超锅锅的博客-CSDN博客_fscanf 段错误
代码如下:

#include <stdio.h>
#include <stdlib.h>  //为rand()函数提供原型 
#define N 100
struct stu{
    int id;
    int english;
    int math;
    int chinese;
    double total;
}; 

//https://blog.csdn.net/qq_41666142/article/details/104797239
//判断语文、数学、英语的最低分 
int findMinScore(int english,int math,int chinese){
    
    int min = english;
    
    if(min>math){
        min = math;
    }
    
    if(min>chinese){
        min = chinese;
    }
    
    return min;
}


int main(void){
    
    
    
    //https://jingyan.baidu.com/article/a378c9608fd37df2282830db.html
    //因为score.txt里面需要有100名学生成绩的数据,所以用下面的办法产生数据 
    int i,j;
    struct stu scores[N];
    FILE * fp;
        
// 用于生成100个学生成绩等信息 
//     fp = fopen("score.txt","w");
//    if(fp==NULL){
//        printf("文件打开或创建失败!\n");
//        return 0;
//    }
//    for(i=0;i<N;i++){
//        
//        scores[i].id = i+1; 
//        scores[i].english = rand()%100+1;
//        scores[i].math = rand()%100+1;
//        scores[i].chinese = rand()%100+1;
//        fprintf(fp,"%d %d %d %d ",scores[i].id,scores[i].english,scores[i].math,scores[i].chinese);        
//    }
//    fclose(fp);
//    
    //printf("0\n");
    
  //用于测试读取文件 
//    fp = fopen("score.txt","r");
//    if(fp==NULL){
//        printf("文件打开或创建失败!\n");
//        return 0;
//    } 
//    char ch;
//    fscanf(fp,"%c",&ch);
//    printf("ch=%d\n",ch);
//    fclose(fp); 
    
    fp = fopen("score.txt","r");
    if(fp==NULL){
        printf("文件打开或创建失败!\n");
        return 0;
    } 
    //fscanf读取数据时,整数读取后面的变量要加&取址 
    //https://blog.csdn.net/candcplusplus/article/details/7060633
    //读取数据到学生结构数组 
    for(i=0;i<N;i++){
    //    printf("读取i=%d ",i);
        fscanf(fp,"%d %d %d %d ",&scores[i].id,&scores[i].english,&scores[i].math,&scores[i].chinese);    
        scores[i].total = scores[i].english+scores[i].math+scores[i].chinese;    
    }
    fclose(fp);
    
    //printf("1\n");
    int temp;
    double dtemp;
    //按题目要求排序学生结构数组的数据 
    for(i=0;i<N-1;i++){
        
        for(j=i;j<N;j++){
            
            if(scores[i].total<scores[j].total){  //总分高的排前面 ,通过交换数值完成数组元素的交换 
                
                temp = scores[i].id;
                scores[i].id = scores[j].id;
                scores[j].id = temp;
                
                temp = scores[i].english;
                scores[i].english = scores[j].english;
                scores[j].english = temp;
                
                temp = scores[i].math;
                scores[i].math = scores[j].math;
                scores[j].math = temp;
                
                temp = scores[i].chinese;
                scores[i].chinese = scores[j].chinese;
                scores[j].chinese = temp;
                
                dtemp = scores[i].total;
                scores[i].total = scores[j].total;
                scores[j].total = dtemp;
            }
            
            if(scores[i].total==scores[j].total  //总分相同,最低分高的排前面 ,通过交换数值完成数组元素的交换 
                &&
                (
                findMinScore(scores[i].english,scores[i].math,scores[i].chinese)
                    <
                findMinScore(scores[i].english,scores[j].math,scores[j].chinese)            
                )
            ){
                temp = scores[i].id;
                scores[i].id = scores[j].id;
                scores[j].id = temp;
                
                temp = scores[i].english;
                scores[i].english = scores[j].english;
                scores[j].english = temp;
                
                temp = scores[i].math;
                scores[i].math = scores[j].math;
                scores[j].math = temp;
                
                temp = scores[i].chinese;
                scores[i].chinese = scores[j].chinese;
                scores[j].chinese = temp;
                
                dtemp = scores[i].total;
                scores[i].total = scores[j].total;
                scores[j].total = dtemp;            
            }
            
            if((scores[i].total==scores[j].total) //总分相同,最低分也相同,则学号小的排前面 ,通过交换数值完成数组元素的交换 
                &&
                (
                findMinScore(scores[i].english,scores[i].math,scores[i].chinese)
                    ==
                findMinScore(scores[i].english,scores[j].math,scores[j].chinese)            
                )
                &&
                (scores[i].id>scores[j].id)
                
            ){
                temp = scores[i].id;
                scores[i].id = scores[j].id;
                scores[j].id = temp;
                
                temp = scores[i].english;
                scores[i].english = scores[j].english;
                scores[j].english = temp;
                
                temp = scores[i].math;
                scores[i].math = scores[j].math;
                scores[j].math = temp;
                
                temp = scores[i].chinese;
                scores[i].chinese = scores[j].chinese;
                scores[j].chinese = temp;
                
                dtemp = scores[i].total;
                scores[i].total = scores[j].total;
                scores[j].total = dtemp;            
            }
        
        }
    }
    
    //用于测试,
//    printf("读取的学生成绩信息排序后:\n");
//    for(i=0;i<N;i++){
//        printf("学号:%d, 英语:%d, 数学:%d, 语文:%d, 总分:%lf\n",
//        scores[i].id,scores[i].english,scores[i].math,scores[i].chinese,scores[i].total);
//        
//    } 
    
    int n;
    //获取要查询第哪一位的学生 
    printf("请输入要查询成绩总分第多少位的同学:");
    scanf("%d",&n);
    
    //经过排序后的结构数组的第n-1位的元素即题目所求 
    printf("%d %lf %d",scores[n-1].id, scores[n-1].total, findMinScore(scores[n-1].english, scores[n-1].math, scores[n-1].chinese));
    
    return 0;
    
} 

img