班上有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
运行结果:
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);
}
运行结果:
用二进制文件格式完成上题任务 :
#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);
}
运行结果:
用二进制文件格式完成该题的关键就是要弄清楚fwrite和fread这两个函数的用法,在理解题目要求,该题目要求其实不太明确,给本人做题带来了一些困扰,所以前面用了两种方法些不用二进制格式的。