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
#include
#define COURSE_MAXNUM 5
//声明结构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;
//声明外部函数,函数在其它源文件中实现
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); //关闭文件
}