2020年05月13日 23:21 __ _ _ _ _

文章配图

**The conquest of today, coward lamented yesterday, idle waiting for tomorrow.
**

强者征服今天,懦夫哀叹昨天,懒汉坐等明天。####**
**####**本题代码比以前的代码要多一些,建议要弄懂。
**####任务描述:

本关要求编写函数ReadStudInfo和SaveResult。

编程要求

本关的编程任务是补全step2/fileTxt.c文件中ReadStudInfo函数和SaveResult函数,以实现按格式使用FILE结构存取学生信息的功能。具体要求如下:
1.ReadStudInfo函数功能: 实现从文本文件中读取学生的基本信息。函数ReadStudInfo函数原型为:

void ReadStudInfo(const char *fileName, STUDENT stud[]);

其中:

参数fileName是一个文本文件,位于当前目录,即与源程序文件在同一文件夹下。文件中首先是以字符形式写入的学生人数(整数n,不超过30)和课程数量(整数n,不超过5),然后是n个学生的信息,学生信息在结构STUDENT中定义:


struct student{  long studentID;  char studentName[20];  char sex[4];  struct{      int year;      int month;      int day;  }birthday;  float score[COURSE_MAXNUM];  float total;  float average;  int rank;};typedef struct student STUDENT;
  • 文件中没有存储 total,average,rank 三项信息。

  • 函数ReadStudInfo的第二个参数stud存放读取出来的学生信息。

2.SaveResult函数功能: 实现从文本文件中读取学生的基本信息。函数SaveResult函数原型为:

void SaveResult(const char *fileName, STUDENT stud[],int n,int m);

其中:

  • 参数fileName是一个文本文件,位于当前目录,即与源程序文件在同一文件夹下。

  • 文件中首先要求以字符形式写入学生人数(整数n,不超过30)和课程数量(整数n,不超过5),然后是n个学生的信息。n个学生的信息存放在第二个参数stud开始的n个结构体数据单元中。

  • 每个学生的信息包括学号、姓名、性别、出生日期,若干门课程的成绩、总分、平均分、名次。

测试样例:

文章配图

源代码(题中主函数已提供,只需补充部分函数):


#include <stdio.h>#include <stdlib.h>#define COURSE_MAXNUM 5//声明结构STUDENTstruct student{    long studentID;    char studentName[20];    char sex[4];    struct{        int year;        int month;        int day;    }birthday;    float score[COURSE_MAXNUM];    float total;    float average;    int rank;};typedef struct student STUDENT;
//声明外部函数,函数在其它源文件中实现extern void ReadStudInfo(const char *fileName, STUDENT stud[]);extern void SaveResult(const char *fileName, STUDENT stud[],int n,int m);//声明本文件中的其它函数void Input(STUDENT *stud, int n,int m);void Print(STUDENT *stud, int n,int m);void TotalAndAverage(STUDENT *stud, int n,int m);void RankByTotal(STUDENT *stud, int n,int m);void SaveStudInfo(const char *fileName,STUDENT *stud,int n,int m);void ReadResult(const char *fileName,STUDENT *stud);
int main(){    int n,m;    //n用于存放学生人数,m用于存放课程门数。    STUDENT *stud; //指向存放学生信息的存储块的首地址
    //freopen("Input.txt","r",stdin);    scanf("%d%d",&n,&m); //输入学生总人数    //printf("n=%d,m=%d",n,m);    // 动态分配存储    stud = (STUDENT *)malloc(n*sizeof(STUDENT));    Input(stud,n,m);//输入学生信息    //Print(stud,n,m);    //将测试输入信息写入文件    SaveStudInfo("student.txt",stud,n,m);    free(stud);
    //打开文件student.txt,以文本文件方式打开用于读    //从文件中读取学生信息到数组stud中    stud = (STUDENT *)malloc(n*sizeof(STUDENT));    ReadStudInfo("student.txt",stud);//在filetxt中    // 计算总分    TotalAndAverage(stud,n,m);    // 计算排名    RankByTotal(stud,n,m);    //Print(stud,n,m);    //打开文件result.txt,以文本文件方式打开用于写    //将计算出了总分和平均分以及名次的学生信息写入文件    SaveResult("result.txt",stud,n,m);//在filetxt中    free(stud);
    //打开文件result.txt,以文本文件方式打开用于读    //从文件中读取学生信息到数组stud中,用于测试是否与预期输出一致    stud = (STUDENT *)malloc(n*sizeof(STUDENT));    ReadResult("result.txt",stud);    //输出学生信息    Print(stud,n,m);    free(stud);    return 0;}
void Input(STUDENT *stud, int n,int m){    int i;    //freopen("Input.txt","r",stdin);    //scanf("%d%d",&n,&m);    for(i=0;i<n;i++)    {        scanf("%ld",&stud[i].studentID);        scanf("%s",stud[i].studentName);        scanf("%s",stud[i].sex);        scanf("%d-%d-%d",&stud[i].birthday.year,&stud[i].birthday.month,&stud[i].birthday.day);        for(int j=0;j<m;j++)            scanf("%f",&stud[i].score[j]);        stud[i].total = 0;        stud[i].average = 0;        stud[i].rank = 0;        //printf("i=%d\n",i);    }}void Print(STUDENT *stud, int n,int m){    printf("%8s%12s%4s%12s%10s%10s%10s%10s%10s%10s%5s\n",           "  NO.  ","Name","Sex"," Birthday ","Computer","English","Math","Music","Total","Average","Rank");    for(int i=0;i<n;i++)    {        printf("%8ld",stud[i].studentID);        printf("%15s",stud[i].studentName);        printf("%5s",stud[i].sex);        printf("%6d-%02d-%02d",stud[i].birthday.year,stud[i].birthday.month,stud[i].birthday.day);        for(int j=0;j<m;j++)        {            printf("%10.0f",stud[i].score[j]);        }        printf("%10.0f",stud[i].total);        printf("%10.0f",stud[i].average);        printf("%5d\n",stud[i].rank);    }}
void TotalAndAverage(STUDENT *stud, int n,int m){    for(int i=0;i<n;i++)    {        stud[i].total = 0;        for(int j=0;j<m;j++)            stud[i].total += stud[i].score[j];
        stud[i].average = stud[i].total/4;    }}
void RankByTotal(STUDENT *stud, int n,int m){
    for(int i=0;i<n-1; i++)    {        int k = i;        for(int j=i+1;j<n;j++)        {            if(stud[j].total>stud[k].total)            {                k = j;            }        }        if(k != i)        {            STUDENT temp = stud[i];            stud[i] = stud[k];            stud[k] = temp;        }        stud[i].rank = i+1;        if(i>0 && stud[i].total == stud[i-1].total)            stud[i].rank = stud[i-1].rank;    }    stud[n-1].rank = n;    if(n-1>0 && stud[n-1].total == stud[n-2].total)        stud[n-1].rank = stud[n-2].rank;}
void SaveStudInfo(const char *fileName,STUDENT *stud,int n,int m){    FILE *fp = fopen(fileName,"w");  //打开文本文件student.txt用于写    if(fp == NULL)    {        printf("Failure to open %s!\n",fileName);        exit(0);    }    fprintf(fp,"%d %d",n,m);//将n,m写入文件
    for(int i=0;i<n;i++)    {        fprintf(fp,"\n%-12ld\t",stud[i].studentID);        fprintf(fp,"%-12s\t",stud[i].studentName);        fprintf(fp,"%-4s\t",stud[i].sex);        fprintf(fp,"%4d-%02d-%02d\t",stud[i].birthday.year,stud[i].birthday.month,stud[i].birthday.day);        for(int j=0;j<m;j++)            fprintf(fp,"%.0f\t",stud[i].score[j]);    }    fclose(fp); //关闭文件}
void ReadResult(const char *fileName,STUDENT *stud){    FILE *fp = fopen(fileName,"r");  //打开文本文件result.txt用于读    if(fp == NULL)    {        printf("Failure to open %s!\n",fileName);        exit(0);    }    int n,m;    fscanf(fp,"%d%d",&n,&m);    for(int i=0;i<n;i++)    {        fscanf(fp,"%ld",&stud[i].studentID);        fscanf(fp,"%s",stud[i].studentName);        fscanf(fp,"%s",stud[i].sex);        fscanf(fp,"%d-%d-%d",&stud[i].birthday.year,&stud[i].birthday.month,&stud[i].birthday.day);        for(int j=0;j<m;j++)            fscanf(fp,"%f",&stud[i].score[j]);        fscanf(fp,"%f",&stud[i].total);        fscanf(fp,"%f",&stud[i].average);        fscanf(fp,"%d",&stud[i].rank);    }    fclose(fp);//关闭文件}//从文件fileName表示的文本文件中读取学生基本信息,//包括学号、姓名、性别、出生日期,若干门课程的成绩//文件的第一行存储的信息包含了n和m,即学生的人数和课程门数void ReadStudInfo(const char *fileName, STUDENT stud[]){    FILE *fp = fopen(fileName,"r");  //打开文本文件student.txt用于读    if(fp == NULL)    {        printf("Failure to open %s!\n",fileName);        exit(0);    }    int n,m;    fscanf(fp,"%d%d",&m,&n);    for(int i=0;i<n;i++)    {        fscanf(fp,"%ld",&stud[i].studentID);        fscanf(fp,"%s",stud[i].studentName);        fscanf(fp,"%s",stud[i].sex);        fscanf(fp,"%d-%d-%d",&stud[i].birthday.year,&stud[i].birthday.month,&stud[i].birthday.day);        for(int j=0;j<m;j++)            fscanf(fp,"%f",&stud[i].score[j]);    }    fclose(fp);//关闭文件}
//向文件fileName表示的文本文件中写入学生基本信息,//包括学号、姓名、性别、出生日期,若干门课程的成绩、总分、平均分、名次//文件的第一行存储的信息应该包括n和m,即学生的人数和课程门数void SaveResult(const char *fileName, STUDENT stud[],int n,int m){    FILE *fp = fopen(fileName,"w");  //打开文本文件result.txt用于写    if(fp == NULL)    {        printf("Failure to open %s!\n",fileName);        exit(0);    }    fprintf(fp,"%d %d",n,m);//将n,m写入文件
    for(int i=0;i<n;i++)    {        fprintf(fp,"\n%-12ld\t",stud[i].studentID);        fprintf(fp,"%-12s\t",stud[i].studentName);        fprintf(fp,"%-4s\t",stud[i].sex);        fprintf(fp,"%4d-%02d-%02d\t",stud[i].birthday.year,stud[i].birthday.month,stud[i].birthday.day);        for(int j=0;j<m;j++)            fprintf(fp,"%.0f\t",stud[i].score[j]);        fprintf(fp,"%.0f\t",stud[i].total);        fprintf(fp,"%.0f\t",stud[i].average);        fprintf(fp,"%d",stud[i].rank);    }    fclose(fp); //关闭文件}

运行结果:

文章配图

文章配图

最后的话:刷题要找自己的不足,然后去专攻。

往期推荐:

递归实现输出一个整数的逆序 2020-05-07
文章配图

在文件中输入字符串HelloWord 2020-05-08
文章配图

文件读取和写入 2020-05-09
文章配图

公众号:程序员Bob

一个正在学习数据结构的人,致力于将所学内容讲得更透彻!

点赞关注谢谢你

长按下图二维码关注,和你一起领悟程序员的魅力。

文章配图

点“ 在看 ” 你懂得

文章配图

预览时标签不可点

阅读




__