m0_71469623 2022-07-16 11:51 采纳率: 89.5%
浏览 112
已结题

c语言 读取文件并排序输出

score.txt 是100名学生的成绩数据,每行数据从左至右是学号、英语分数、数学分数和语文分数,用空格隔开。
输入整数 n (1≤ n ≤100)时,创建一个程序来输出显示三个科目成绩总分在前n位学生的学生 id,以及目标学生的总分。
但是,如果总分相同,则将三门课程分数中最低分较高的学生视为更高的排名; 如果分数最低分也相同,则将学号较小的学生视为更高的排名。
在编写程序时,我们只需要利用 score.txt 中描述的学生人数100人编写代码,只有当学生人数为100人时才能正常工作。
中间那段没太懂,请问应该怎么写比较好呢,如果有步骤说明就更好了,谢谢。

  • 写回答

2条回答 默认 最新

  • 微尘8 2022-07-16 19:40
    关注
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #define MIN 1
    #define MAX 100
    #define BUFF_SIZE 100
    
    struct S_STUDENT
    {   
        int id;
        int english; //英语分数
        int math;    //数学分数
        int chinese; //语文分数
        int total;   //总分
        int min;     //最低分
    };
    
    int output_student_score(const char* pScoreFile, int n);
    int find_min(int a, int b);
    void insert_student(struct S_STUDENT *pStudent, int len, struct S_STUDENT stu);
    
    int main()
    {   
        int n = 0;
        
        printf("please input a number(1-100):");
        int ret = scanf("%d", &n);
        if (ret == 0)
        {   
            fprintf(stderr, "输入的不是数字\n");
            return -1;
        }
        if (n > MAX || n < MIN)
        {   
            fprintf(stderr, "输入的数字不在1-100范围内\n");
            return -1;
        }
        
        output_student_score("./score.txt", n);
        
        return 0;
    }
    
    int find_min(int a, int b)
    {   
        return (a < b) ? a : b;
    }
    
    int is_high_student(struct S_STUDENT *pSrcStu, struct S_STUDENT *pDesStu)
    {
        if (pDesStu->total > pSrcStu->total)
            return 1;
    
        if (pDesStu->total == pSrcStu->total)
        {
            if (pDesStu->min > pSrcStu->min)
                return 1;
    
            if (pDesStu->min == pSrcStu->min)
            {
                if (pDesStu->id < pSrcStu->id)
                    return 1;
            }
        }
    
        return 0;
    }
    
    int output_student_score(const char* pScoreFile, int n)
    {
        FILE *fp = fopen(pScoreFile, "r");
        if (!fp)
        {
            fprintf(stderr, "打开文件错误");
            return -1;
        }
    
        char readBuf[BUFF_SIZE];
        char *pStr = NULL;
        struct S_STUDENT student[MAX];
        int row = 0;
        while(fgets(readBuf, BUFF_SIZE, fp))
        {
            struct S_STUDENT stu;
            int column = 0;
            pStr = strtok(readBuf, " ");
            while(pStr)
            {
                switch (column)
                {
                    case 0:
                        stu.id = atoi(pStr);
                        break;
                    case 1:
                        stu.english = atoi(pStr);
                        break;
                    case 2:
                        stu.math = atoi(pStr);
                        break;
                    default:
                        stu.chinese = atoi(pStr);
                        break;
                }
                pStr = strtok(NULL, " ");
                column++;
            }
    
            stu.total = stu.english + stu.math + stu.chinese;
            stu.min =  find_min(find_min(stu.english, stu.math), stu.chinese);
            insert_student(student, row, stu);
            row++;
        }
    
        fclose(fp);
    
        int i;
        for (i = 0; i < n; i++)
        {
            printf("id = %d, total = %d, min = %d\n", student[i].id, student[i].total, student[i].min);
        }
    }
    
    void insert_student(struct S_STUDENT *pStudent, int len, struct S_STUDENT stu)
    {
        if (len == 0)
        {
            pStudent[0] = stu;
            return;
        }
    
        int i,j;
        struct S_STUDENT s_temp;
        int high = 0;
        for (i = 0; i < len; i++)
        {
            high = is_high_student(&pStudent[i], &stu);
            if (high)
            {
                for (j = len-1; j >= i; j--)
                {
                    s_temp.id = pStudent[j].id;
                    s_temp.english = pStudent[j].english;
                    s_temp.math = pStudent[j].math;
                    s_temp.chinese = pStudent[j].chinese;
                    s_temp.total = pStudent[j].total;
                    s_temp.min = pStudent[j].min;
    
                    pStudent[j + 1] = s_temp;
                }
                pStudent[i] = stu;
    
                break;
            }
        }
    
        if (!high)
        {
            pStudent[len] = stu;
        }
    }
    

    img

    img

    设计思路:
    1.分析题,定义一个存储学生成绩表的结构体。
    2.利用fopen函数打开score.txt,再利用fget函数读取每一行数据,再利用strtok函数分割每一行,得到id,英语分数,数学分数,语文分数
    3.将读取到的每个学生的成绩按照题目中说的总分高的排在前面,如果两个学生三科总分一样的话,就比较这两位学生三科成绩中分数最低的那科,
    三科成绩中分数最低的那科的分数高的那位学生排在前面,如果两位学生的三科总分一样,而且两位学生三科成绩中分数最低的那科的分数也一样,
    则将学号较小的学生视为更高的排名。
    4.步骤3中读取到的学生,放在数组中,都已经排序排好了的,所以不管程序输入1-100之间的任何数,直接输出到屏幕,就可以啦

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 7月24日
  • 已采纳回答 7月16日
  • 创建了问题 7月16日

悬赏问题

  • ¥15 已知平面坐标系(非直角坐标系)内三个点的坐标,反求两坐标轴的夹角
  • ¥15 webots有问题,无响应
  • ¥15 数据量少可以用MK趋势分析吗
  • ¥15 使用VH6501干扰RTR位,CANoe上显示的错误帧不足32个就进入bus off快慢恢复,为什么?
  • ¥15 大智慧怎么编写一个选股程序
  • ¥100 python 调用 cgps 命令获取 实时位置信息
  • ¥15 两台交换机分别是trunk接口和access接口为何无法通信,通信过程是如何?
  • ¥15 C语言使用vscode编码错误
  • ¥15 用KSV5转成本时,如何不生成那笔中间凭证
  • ¥20 ensp怎么配置让PC1和PC2通讯上