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

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 java map类型数据格式,如何快速通过前缀匹配元素
  • ¥15 stc12c5a60s2、QMC5883L、LCD1602组合测量磁场所需程序
  • ¥15 vba参数转c++ SAFEARRAY
  • ¥20 Win11测试yolov4,“找不到nvcuda.dll”怎么办?
  • ¥15 simulink绘制bode图
  • ¥15 php_network_getaddresses: getaddrinfo failed: Name or service not known
  • ¥15 用msg发消息出现的问题
  • ¥15 unity3d机械臂
  • ¥20 判断两个表是否完全相同
  • ¥20 工控机出现散热器转一下停一下这种情况,是什么原因造成的