Description
数据库文件aaa.dic、bbb.dic、ccc.dic中都存有若干(不超过100个)学生的数据,已知三个文件中都有name、english、math三个字段。
请编程序,从键盘输入1或2或3以打开aaa.dic或bbb.dic或ccc.dic,读出所有学生的name和english、math成绩并按总分由高到低的顺序输出每个学生的数据。若总分相同,english分数高的排前。
注意:有些记录已被删除,被删记录属于无效记录
输出格式:每行一个学生的数据,姓名占10格(左对齐),两科成绩各占4格,总分占5格(除姓名外,其他数据都保留一位小数,右对齐,后面三个数据之间用一个空格隔开)
如:
zhangsan 90.5 87.0 177.5
lisi 88.0 89.0 177.0
Input
输入1或2或3
Output
按总分从高到低输出所有学生的数据
如:
zhangsan 90.5 87.0 177.5
lisi 88.0 89.0 177.0
Sample Input
1
Sample Output
zhangsan 90.5 87.0 177.5
lisi 88.0 89.0 177.0
Code 1 here:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct{
char file_type;//文件特征标志
char date[3];//建表或最后修改时间
int rec_num;//记录总数
short head_size;//文件头的总长度
short rec_size;//每条记录的长度
char empty[20];//空字节
}HEAD;
typedef struct{
char name[10];//字段名
char empty_c;//一个空字节
char type;//字段类型
int begin;//本字段在记录中的起始位置
char width;//字段宽度
char digit;//小数位数
char empty[14]; //空字节
}FIELD;
typedef struct{
char name[11];
float english;
float math;
float sum;
}STUDENT;
int main()
{
FILE *fp;
int i,a,b,j,k,m;
char name[11]="0",s[11]="0",name1[11]="0",c;
HEAD head;
FIELD field[4];
STUDENT student[101];
scanf("%d",&b);
if(b==1)
{
if((fp=fopen("aaa.dic","rb"))==NULL)
exit(1);
}
if(b==2)
{
if((fp=fopen("bbb.dic","rb"))==NULL)
exit(1);
}
if(b==3)
{
if((fp=fopen("ccc.dic","rb"))==NULL)
exit(1);
}
fread(&head,32,1,fp);
a=(head.head_size-32-1)/32;//字段长度
m=head.rec_num;//m先等于记录的总数
for(i=1;i<=a;i++)//找三个字段的位置
{
fread(&field[0],32,1,fp);
if(strcmp(field[0].name,"name")==0)
{
field[1]=field[0];
}
if(strcmp(field[0].name,"english")==0)
{
field[2]=field[0];
}
if(strcmp(field[0].name,"math")==0)
{
field[3]=field[0];
}
}
for(j=0;j<head.rec_num;j++)//跳记录,怎么结束呢,上面有了
{
fseek(fp,head.head_size,0);//跳整个文件头
fseek(fp,head.rec_size*j,1);//跳记录
fread(&c,1,1,fp);//看是否逻辑删除
if(c==42){
m=m-1;//删了几个字段,m减少几个
continue;//注意跳过的结构体没有存值,里面的变量全为0
}
fseek(fp,-1,1);//再跳回去,便于继续找字段的位置
fseek(fp,field[1].begin,1);//跳到name的位置
fread(&name,field[1].width,1,fp);
for(i=field[1].width-1;i>=0;i--)//是空格时添0,注意数组是要-1的
{
if(name[i]==32||name[i]=='\0')
name[i]='\0';
else
break;
}
strcpy(student[j].name,name);//name的复制
fseek(fp,head.head_size,0);//跳文件头
fseek(fp,head.rec_size*j,1);//跳记录
fseek(fp,field[2].begin,1);//跳到english的位置
fread(&s,field[2].width,1,fp);//读
student[j].english=(float)atof(s);
fseek(fp,head.head_size,0);//跳文件头
fseek(fp,head.rec_size*j,1);//跳记录
fseek(fp,field[3].begin,1);//跳到math的位置
fread(&s,field[3].width,1,fp);//读
student[j].math=(float)atof(s);
student[j].sum=student[j].english+student[j].math;
}
for(j=0;j<head.rec_num;j++)
{
for(k=0;k<head.rec_num;k++)
{
if(student[k+1].sum>student[k].sum)//两两交换
{
student[100]=student[k];
student[k]=student[k+1];
student[k+1]=student[100];
}
if(student[k+1].sum==student[k].sum)
{
if(student[k+1].english>student[k].english)
{
student[100]=student[k];
student[k]=student[k+1];
student[k+1]=student[100];
}
}
}
}
for(i=0;i<m;i++)//m是有数据的个数
printf("%-10s%4.1f %4.1f
%5.1f\n",student[i].name,student[i].english,student[i].math,student[i].sum);
fclose(fp);
return 0;
}
可以在此题基础上增加一些简单的变化,比如增加一门计算机computer的成绩,计算成绩的平均值even,下面是完整代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct{
char biaozhi;
char shijian[3];
int zongshu;
short long1;
short long2;//每条记录的长度
char empty[20];
}HEAD;
typedef struct{
char name[10];
char empty_c;
char leixing;
int weizhi;
char long3;
char weishu;
char empty[14];
}FIELD;
typedef struct{
char name[11];
float english;
float math;
float computer;
float sum;//总分
float even;//平均分
}STUDENT;
int main()
{
FILE *fp;
int i,a,b,j,k,m;
float score;
char name[11]="0",s[11]="0",name1[11]="0",c;
HEAD head;
FIELD field[5];
STUDENT student[101];
scanf("%d",&b);
if(b==1)
{
if((fp=fopen("aaa.dic","rb"))==NULL)
exit(1);
}
if(b==2)
{
if((fp=fopen("bbb.dic","rb"))==NULL)
exit(1);
}
if(b==3)
{
if((fp=fopen("ccc.dic","rb"))==NULL)
exit(1);
}
fread(&head,32,1,fp);
a=(head.long1-32-1)/32;//字段长度
m=head.zongshu;
for(i=1;i<=a;i++)//找name的位置
{
fread(&field[0],32,1,fp);
if(strcmp(field[0].name,"姓名")==0)
{
field[1]=field[0];
}
if(strcmp(field[0].name,"英语")==0)
{
field[2]=field[0];
}
if(strcmp(field[0].name,"数学")==0)
{
field[3]=field[0];
}
if(strcmp(field[0].name,"计算机")==0)
{
field[4]=field[0];
}
}
for(j=0;j<head.zongshu;j++)//跳记录,怎么结束呢,上面有了
{
fseek(fp,head.long1,0);//跳整个文件头
fseek(fp,head.long2*j,1);//跳记录
fread(&c,1,1,fp);//看是否逻辑删除
if(c==42){
m=m-1;
continue;
}
fseek(fp,-1,1);
fseek(fp,field[1].weizhi,1);//跳到name的位置
fread(&name,field[1].long3,1,fp);
for(i=field[1].long3-1;i>=0;i--)//是空格时添0,注意数组是要-1的
{
if(name[i]==32||name[i]=='\0')
name[i]='\0';
else
break;
}
strcpy(student[j].name,name);
fseek(fp,head.long1,0);//跳文件头
fseek(fp,head.long2*j,1);//跳记录
fseek(fp,field[2].weizhi,1);//跳到english的位置
fread(&s,field[2].long3,1,fp);//读
student[j].english=(float)atof(s);
fseek(fp,head.long1,0);//跳文件头
fseek(fp,head.long2*j,1);//跳记录
fseek(fp,field[3].weizhi,1);//跳到math的位置
fread(&s,field[3].long3,1,fp);//读
student[j].math=(float)atof(s);
fseek(fp,head.long1,0);//跳文件头
fseek(fp,head.long2*j,1);//跳记录
fseek(fp,field[4].weizhi,1);//跳到computer的位置
fread(&s,field[4].long3,1,fp);//读
student[j].computer=(float)atof(s);
student[j].sum=student[j].english+student[j].math+student[j].computer;
student[j].even=student[j].sum/3;
}
for(j=0;j<head.zongshu;j++)
{
for(k=0;k<head.zongshu;k++)
{
if(student[k+1].sum>student[k].sum)
{
student[100]=student[k];
student[k]=student[k+1];
student[k+1]=student[100];
}
if(student[k+1].sum==student[k].sum)
{
if(student[k+1].english>student[k].english)
{
student[100]=student[k];
student[k]=student[k+1];
student[k+1]=student[100];
}
}
}
}
for(i=0;i<m;i++)
printf("%-10s%4.1f %4.1f %5.1f %.1f\n",student[i].name,student[i].english,student[i].math,student[i].sum,student[i].even);
fclose(fp);
return 0;
}
只进行了一下小改动,在以前的代码的基础上改的,有些变量没写成英文(懒得改,都一样)~