结构体应用,二进制文件格式完成

班上有30人,每人有学号,数学,英语,c语言3门课程的成绩数据。编程完成如下任务:

 

1、将数据输入到文本文件score.txt

2、计算每人总分,将学号,数学,英语,c语言,总分等数据按总分从高到低输出每位同学的全部数据。

3、将每位同学的数据按学号顺序计算输出各同学的总分排名,分数最高的名次为1,分数相同的名次相同,若有i个同学排在第x位,则下个分数的名次为x+i位。并将这些数据均写入文本文件newscore.txt

1,假设有score.txt文件在,直接进行文件操作:

#include <stdio.h>
#include <stdlib.h>
struct students
{
    int num;//学号
    double ma;//数学成绩
    double en;//英语成绩
    double cl;//C语言成绩
    double sum;//总分
    int no;//排名
} stu[30];
int nop = 0;//读取的学生人数,省得传参数
void input();//将score.txt中数据存入stu数组中
void operator_rank_output();//求总分,按总分排名输出
void order_output_save();//按学号顺序输出并存入到newscore.txt中
int main()
{
    input();
    operator_rank_output();
    order_output_save();
    return 0;
}
void input()
{
    FILE * fp;
    if((fp = fopen("score.txt","r")) == NULL)
    {
        printf("文件不存在或无法打开!\n");
        exit(0);
    }
    while(fscanf(fp,"%d%lf%lf%lf",&stu[nop].num,&stu[nop].ma,&stu[nop].en,&stu[nop].cl) != EOF)
    {
        //printf("%-3d %-4.1lf %-4.1lf %-4.1lf\n",stu[nop].num,stu[nop].ma,stu[nop].en,stu[nop].cl);//用于测试输入是否成功
        nop++;
    }
    fclose(fp);//注意要关闭文件,虽然不会报错,但又一定的安全隐患
}
void operator_rank_output()
{
    int i = 0,j = 0;
    for(i = 0; i < nop; i++) //求总分
    {
        stu[i].sum = stu[i].ma + stu[i].en + stu[i].cl;
        //printf("%d %d %d %-4.1lf\n",nop,i,stu[i].num,stu[i].sum);//测试运算结果
    }
    for(i = 0 ; i < nop ; i++)
        for(j = 0 ; j < nop - 1 ; j++)
            if(stu[j].sum < stu[j+1].sum)
            {
                struct students tp = stu[j];
                stu[j] = stu[j+1];
                stu[j+1] = tp;
            }
    for(i = 0; i < nop; i++)//赋予学生排名,暂时不管总分相同
    {
        stu[i].no = i+1;
        //printf("总分:%-4.1lf 学号:%d 排名:%d\n",stu[i].sum,stu[i].num,stu[i].no);//测试结果
    }
    for(i = 0; i < nop; i++)//处理总分相同的学生
    {
        while((stu[i].sum == stu[i+1].sum) && i+1 < nop)
        {
            stu[i+1].no = stu[i].no;
            i++;
        }
    }
    //下面将数据按要求输出
    printf("学号 数学 英语 C语言 总分\n");
    for(i = 0; i < nop; i++)
        printf(" %-3d %-3.1lf %-3.1lf %-3.1lf  %-4.1lf\n",stu[i].num,stu[i].ma,stu[i].en,stu[i].cl,stu[i].sum);
}
void order_output_save()
{
    int i = 0,j = 0;
    for(i = 0 ; i < nop ; i++)
        for(j = 0 ; j < nop - 1 ; j++)
            if(stu[j].num > stu[j+1].num)
            {
                struct students tp = stu[j];
                stu[j] = stu[j+1];
                stu[j+1] = tp;
            }
    FILE * fp;
    if((fp = fopen("newscore.txt","w")) == NULL)
    {
        printf("文件不存在或无法打开!\n");
        exit(0);
    }
    printf("\n\n学号 数学 英语 C语言 总分   排名\n");
    fprintf(fp,"学号   数学  英语  C语言   总分   排名\n");
    for(i = 0; i < nop; i++)
    {
        printf(" %-3d %-3.1lf %-3.1lf %-3.1lf  %-4.1lf %3d\n",stu[i].num,stu[i].ma,stu[i].en,stu[i].cl,stu[i].sum,stu[i].no);//输出到屏幕
        fprintf(fp," %-3d  %-3.1lf  %-3.1lf  %-3.1lf   %-4.1lf %3d\n",stu[i].num,stu[i].ma,stu[i].en,stu[i].cl,stu[i].sum,stu[i].no);//输出到newscore.txt文件
    }
    fclose(fp);
}

score.txt文件内容:(30太多,10个数据就可以看到结果,当然有30个数据也是可以处理的)

1 80 80 80
2 75 69 89
3 88 78 88
4 79 97 56
5 89 78 64
6 97 78 86
7 97 78 86
8 88 78 88
9 88 78 88
10 80 80 80

运行结果:

d14c0b2713b30a39dbeab2a70de2276c.png

5383f09837c9a819539f5004e52a2013.png

2.如果score.txt文件不存在,而从控制台手输入数据并创建score.txt文件:

#include <stdio.h>
#include <stdlib.h>
struct students
{
    int num;//学号
    double ma;//数学成绩
    double en;//英语成绩
    double cl;//C语言成绩
    double sum;//总分
    int no;//排名
} stu[30];
int nop = 0;//读取的学生人数,省得传参数
void input();//输入数据以存入stu数组和score.txt中
void operator_rank_output();//求总分,按总分排名输出
void order_output_save();//按学号顺序输出并存入到newscore.txt中
int main()
{
    input();
    operator_rank_output();
    order_output_save();
    return 0;
}
void input()
{
    FILE * fp;
    if((fp = fopen("score.txt","w")) == NULL)
    {
        printf("文件无法创建!\n");
        exit(0);
    }
    printf("请输入学生学号,数学成绩,英语成绩,C语言成绩,输入完成请按ctrl+z后按enter结束输入:\n");
    while((scanf("%d%lf%lf%lf",&stu[nop].num,&stu[nop].ma,&stu[nop].en,&stu[nop].cl)) != EOF)
    {
        fprintf(fp,"%d %.1lf %.1lf %.1lf\n",stu[nop].num,stu[nop].ma,stu[nop].en,stu[nop].cl);
        nop++;
    }
    fclose(fp);
}
void operator_rank_output()
{
    int i = 0,j = 0;
    for(i = 0; i < nop; i++) //求总分
    {
        stu[i].sum = stu[i].ma + stu[i].en + stu[i].cl;
        //printf("%d %d %d %-4.1lf\n",nop,i,stu[i].num,stu[i].sum);//测试运算结果
    }
    for(i = 0 ; i < nop ; i++)
        for(j = 0 ; j < nop - 1 ; j++)
            if(stu[j].sum < stu[j+1].sum)
            {
                struct students tp = stu[j];
                stu[j] = stu[j+1];
                stu[j+1] = tp;
            }
    for(i = 0; i < nop; i++)//赋予学生排名,暂时不管总分相同
    {
        stu[i].no = i+1;
        //printf("总分:%-4.1lf 学号:%d 排名:%d\n",stu[i].sum,stu[i].num,stu[i].no);//测试结果
    }
    for(i = 0; i < nop; i++)//处理总分相同的学生
    {
        while((stu[i].sum == stu[i+1].sum) && i+1 < nop)
        {
            stu[i+1].no = stu[i].no;
            i++;
        }
    }
    //下面将数据按要求输出
    printf("学号 数学 英语 C语言 总分\n");
    for(i = 0; i < nop; i++)
        printf(" %-3d %-3.1lf %-3.1lf %-3.1lf  %-4.1lf\n",stu[i].num,stu[i].ma,stu[i].en,stu[i].cl,stu[i].sum);
}
void order_output_save()
{
    int i = 0,j = 0;
    for(i = 0 ; i < nop ; i++)
        for(j = 0 ; j < nop - 1 ; j++)
            if(stu[j].num > stu[j+1].num)
            {
                struct students tp = stu[j];
                stu[j] = stu[j+1];
                stu[j+1] = tp;
            }
    FILE * fp;
    if((fp = fopen("newscore.txt","w")) == NULL)
    {
        printf("文件不存在或无法打开!\n");
        exit(0);
    }
    printf("\n\n学号 数学 英语 C语言 总分   排名\n");
    fprintf(fp,"学号   数学  英语  C语言   总分   排名\n");
    for(i = 0; i < nop; i++)
    {
        printf(" %-3d %-3.1lf %-3.1lf %-3.1lf  %-4.1lf %3d\n",stu[i].num,stu[i].ma,stu[i].en,stu[i].cl,stu[i].sum,stu[i].no);//输出到屏幕
        fprintf(fp," %-3d  %-3.1lf  %-3.1lf  %-3.1lf   %-4.1lf %3d\n",stu[i].num,stu[i].ma,stu[i].en,stu[i].cl,stu[i].sum,stu[i].no);//输出到newscore.txt文件
    }
    fclose(fp);
}

运行结果:

346efebcc13bfa6b86ae17e1f7aede4a.png

da26d6dadea459f53358227fbf5d5bb2.png

c717eae470e2f6f7b44f038c84bf3626.png

 用二进制文件格式完成上题任务 :

#include <stdio.h>
#include <stdlib.h>
struct student
{
    int num;//学号
    double ma;//数学成绩
    double en;//英语成绩
    double cl;//C语言成绩
}stu1[30],stu2[30];
struct students
{
    int num;//学号
    double ma;//数学成绩
    double en;//英语成绩
    double cl;//C语言成绩
    double sum;//总分
    int no;//排名
} stu[30];
int nop = 0;//读取的学生人数,省得传参数
void input();//输入数据以存入stu数组和score.txt中
void get_date_form_binary();//从二进制文件score.txt中获取数据先暂时存入stu2数组中,再将stu2中数据赋值给stu数组,并对stu数组中总分和排名进行初始化
void operator_rank_output();//求总分,按总分排名输出
void order_output_save();//按学号顺序输出并存入到newscore.txt中
int main()
{
    input();
    get_date_form_binary();
    operator_rank_output();
    order_output_save();
    return 0;
}
void input()
{
    FILE * fp;
    if((fp = fopen("score.txt","wb")) == NULL)
    {
        printf("文件无法创建!\n");
        exit(0);
    }
    printf("请输入学生学号,数学成绩,英语成绩,C语言成绩,输入完成请按ctrl+z后按enter结束输入:\n");
    while((scanf("%d%lf%lf%lf",&stu1[nop].num,&stu1[nop].ma,&stu1[nop].en,&stu1[nop].cl)) != EOF)
    {
        fwrite(&stu1[nop],sizeof(stu1[nop]),1,fp);
        nop++;
    }
    fclose(fp);//注意要关闭文件,虽然不会报错,但又一定的安全隐患
}
void get_date_form_binary()
{
    FILE * fp;
    if((fp = fopen("score.txt","rb")) == NULL)
    {
        printf("文件不存在或无法打开!\n");
        exit(0);
    }
    nop = 0;
    while(fread(&stu2[nop],sizeof(stu2[nop]),1,fp) == 1)
    {
        stu[nop].num = stu2[nop].num;
        stu[nop].ma = stu2[nop].ma;
        stu[nop].en = stu2[nop].en;
        stu[nop].cl = stu2[nop].cl;
        stu[nop].sum = 0;
        stu[nop].no = 0;
        nop++;
    }
    fclose(fp);
}
void operator_rank_output()
{
    int i = 0,j = 0;
    for(i = 0; i < nop; i++) //求总分
    {
        stu[i].sum = stu[i].ma + stu[i].en + stu[i].cl;
        //printf("%d %d %d %-4.1lf\n",nop,i,stu[i].num,stu[i].sum);//测试运算结果
    }
    for(i = 0 ; i < nop ; i++)
        for(j = 0 ; j < nop - 1 ; j++)
            if(stu[j].sum < stu[j+1].sum)
            {
                struct students tp = stu[j];
                stu[j] = stu[j+1];
                stu[j+1] = tp;
            }
    for(i = 0; i < nop; i++)//赋予学生排名,暂时不管总分相同
    {
        stu[i].no = i+1;
        //printf("总分:%-4.1lf 学号:%d 排名:%d\n",stu[i].sum,stu[i].num,stu[i].no);//测试结果
    }
    for(i = 0; i < nop; i++)//处理总分相同的学生
    {
        while((stu[i].sum == stu[i+1].sum) && i+1 < nop)
        {
            stu[i+1].no = stu[i].no;
            i++;
        }
    }
    //下面将数据按要求输出
    printf("学号 数学 英语 C语言 总分\n");
    for(i = 0; i < nop; i++)
        printf(" %-3d %-3.1lf %-3.1lf %-3.1lf  %-4.1lf\n",stu[i].num,stu[i].ma,stu[i].en,stu[i].cl,stu[i].sum);
}
void order_output_save()
{
    int i = 0,j = 0;
    for(i = 0 ; i < nop ; i++)
        for(j = 0 ; j < nop - 1 ; j++)
            if(stu[j].num > stu[j+1].num)
            {
                struct students tp = stu[j];
                stu[j] = stu[j+1];
                stu[j+1] = tp;
            }
    FILE * fp;
    if((fp = fopen("newscore.txt","wb")) == NULL)
    {
        printf("文件不存在或无法打开!\n");
        exit(0);
    }
    printf("\n\n学号 数学 英语 C语言 总分   排名\n");
    char str[] = "学号   数学  英语  C语言   总分   排名\t\t\t";
    fwrite(&str,sizeof(str),1,fp);
    fprintf(fp,"学号   数学  英语  C语言   总分   排名\n");
    for(i = 0; i < nop; i++)
    {
        printf(" %-3d %-3.1lf %-3.1lf %-3.1lf  %-4.1lf %3d\n",stu[i].num,stu[i].ma,stu[i].en,stu[i].cl,stu[i].sum,stu[i].no);//输出到屏幕
        fwrite(&stu[nop],sizeof(stu[nop]),1,fp);
        fprintf(fp," %-3d  %-3.1lf  %-3.1lf  %-3.1lf   %-4.1lf %3d\n",stu[i].num,stu[i].ma,stu[i].en,stu[i].cl,stu[i].sum,stu[i].no);//输出到newscore.txt文件
    }
    fclose(fp);
}

运行结果:

0a921e82ba75bcd1164dd7ba334afca9.png

63c908d0636377157c2c1957b360e30a.png

cf5bfe8f65dc4f91ab00466fc4fbb852.png

 

 用二进制文件格式完成该题的关键就是要弄清楚fwrite和fread这两个函数的用法,在理解题目要求,该题目要求其实不太明确,给本人做题带来了一些困扰,所以前面用了两种方法些不用二进制格式的。

 

 

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

浮央乜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值