回复 2楼 wp231957
//就是用这个程序把结构写到这个文件中的,这个程序我试了好几次都是可以运行的,上面那个程序就不行了
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<string.h>
#define MAX 20 //
#define SUB 3 //科目数
typedef struct Student Student;
typedef struct Class Class;
struct Student //定义一个学生的结构
{
char name[MAX]; //学生的名字
double subject[SUB]; //三个科目的分数
double student_average; //一个学生的的平均分
};
struct Class //定义一个班级
{
char class_name[MAX]; //班级名字
Student** student; //存储学生结构的指针
Class* pnext;
double class_average[SUB];
int student_number; //一个班级的人数
};
FILE* pfile=NULL;
char* filename="D:\\蒋臣健\\学生成绩.bin"; //储存班级结构的文件
double get_student(Student* student,double class_average[],size_t n); //返回一个学生的三个科目的分数平均值
Class* get_class(void); //创建一个班级结构
void free_memory(Class* pfirst); //释放堆内存
void list_class(Class* first); //列出班级结构
int camp(char* name,Class* first); //比较输入的名字在不在班级里面
Class* get_class(void)
{
int number=0; //初始化一个班级的学生数目
char ch='a';
Class* pclass=NULL;
if(!(pclass=calloc(1,sizeof(Class))))
{
printf("班级分配内存失败");
exit(1);
}
pclass->student=calloc(MAX,sizeof(Student*)); //存储20个指向学生结构指针的内存
if(!(pclass->student))
{
printf("存放结构的指针的内存失败");
exit(1);
}
printf("请输入班级名字:");
scanf("%s",pclass->class_name);
do //用循环输入一个班级的成员
{
pclass->student[number]=calloc(1,sizeof(Student)); //存储一个学生结构
if(!(pclass->student[number]))
{
printf("学生结构内存分配失败");
exit(2);
}
pclass->student[number]->student_average=get_student(pclass->student[number],pclass->class_average,MAX); //调用输入一个学生结构的函数,把返回值存到一个学生的平均分
++number;
++pclass->student_number; //记录班级人数
fflush(stdin);
printf("还要输入学生成绩吗?");
scanf("%c",&ch);
}while(ch=='y');
return pclass;
}
double get_student(Student* student,double class_average[],size_t n)
{
int i=0;
double average=0.0;
double sum=0.0;
fflush(stdin);
printf("请输入学生姓名:");
scanf("%s",student->name);
for(i=0;i<SUB;i++) //在一个循环里输入一个学生的三个科目的分数
{
switch(i) //控制三个科目分数的顺序
{
case 0:
printf("please enter %s Chinese scores",student->name);
break;
case 1:
printf("please enter %s Maths scores",student->name);
break;
case 2:
printf("please enter %s English scores",student->name);
break;
default:
break;
}
scanf("%lf",&student->subject[i]);
class_average[i]+=student->subject[i]; // 记录一个班级每个科目的平均分
sum+=student->subject[i]; //累加一个学生科目的分数
}
average=sum/SUB; //记录一个学生的平均分
return average;
}
void list_class(Class* first)
{
Class* pcurrent=first; //把头指针复制给临时变量
int b=0;
int i=0;
while(pcurrent!=NULL) //在一个循环里输出班级的成员
{
printf("%s ",pcurrent->class_name);
for(b=0;b<pcurrent->student_number;b++) //for循环输出一个班级的学生,学生的每科分数
{
for(i=0;i<SUB;i++)
{
switch(i) //控制输入每科成绩的顺序
{
case 0:
printf("%s的语文成绩为%.2lf ",pcurrent->student[b]->name,pcurrent->student[b]->subject[i]);
break;
case 1:
printf("%s的数学成绩为%.2lf ",pcurrent->student[b]->name,pcurrent->student[b]->subject[i]);
break;
case 2:
printf("%s的英语成绩为%.2lf\n",pcurrent->student[b]->name,pcurrent->student[b]->subject[i]);
break;
default:
break;
}
}
printf("%s的平均成绩为%.2lf\n",pcurrent->student[b]->name,pcurrent->student[b]->student_average);
}
for(i=0;i<SUB;i++) //输出一个班级的每个科目的总平均分
{
switch(i)
{
case 0:
printf("%s的语文总平均分为%.2lf ",pcurrent->class_name,pcurrent->class_average[i]);
break;
case 1:
printf("%s的数学总平均分为%.2lf ",pcurrent->class_name,pcurrent->class_average[i]);
break;
case 2:
printf("%s的英文总平均分为%.2lf\n",pcurrent->class_name,pcurrent->class_average[i]);
break;
default:
break;
}
}
printf("班级总人数%d",pcurrent->student_number);
pcurrent=pcurrent->pnext;
}
}
void free_memory(Class* pfirst)
{
int b=0;
Class* pcurrent=pfirst;
while(pcurrent!=NULL)
{
Class* ptemp=NULL;
ptemp=pcurrent;
for(b=0;b<pcurrent->student_number;b++)
{
free(pcurrent->student[b]);
pcurrent->student[b]=NULL;
}
free(pcurrent->student);
pcurrent->student=NULL;
pcurrent=pcurrent->pnext;
free(ptemp);
ptemp=NULL;
}
}
int main()
{
char word='y';
Class class_one;
do
{
Class* pfirst=NULL;
Class* previous=NULL;
Class* pcurrent=NULL;
int i=0;
int b=0;
char ch=0;
int student_number=0;
int dex=0; //储存比较函数的返回值
char name[MAX];
if(!(pfile=fopen(filename,"wb")))
{
printf("Failed to open");
exit(1);
}
if(setvbuf(pfile,NULL,_IOFBF,BUFSIZ))
{
printf("file buffering failed");
exit(2);
}
do //用循环生成班级结构链表
{
pcurrent=get_class(); //获取一个班级结构
if(fwrite(pcurrent,sizeof(Class),1,pfile)<1) //把班级结构写入文件
printf("写入失败");
;
if(!pfirst)
pfirst=previous=pcurrent;
else
{
previous->pnext=pcurrent;
previous=pcurrent;
previous->pnext=NULL;
}
fflush(stdin); //清楚输入缓存区
printf("还想输入班级吗");
scanf("%c",&ch);
}while(ch=='y');
list_class(pfirst);
fflush(stdin);
printf("请输入你想要找的学生:");
scanf("%s",name);
if(!(dex=camp(name,pfirst)))
printf("没有这个人");
pfirst=NULL;
fclose(pfile);
if(!(pfile=fopen(filename,"rb")))
{
printf("Failed to open");
exit(1);
}
if(setvbuf(pfile,NULL,_IOFBF,BUFSIZ))
{
printf("file buffering failed");
exit(2);
}
fread(&class_one,sizeof(Class),1,pfile); //从文件中读取结构
printf("sizeof=%d",sizeof(class_one));
for(i=0;i<class_one.student_number;i++)
{
printf("%lf ",class_one.student[i]->student_average);
}
free_memory(pfirst);
pfirst=NULL;
fclose(pfile);
pfile=NULL;
fflush(stdin);
printf("还想再来一次");
scanf("%c",&word);
}while(tolower(word)=='y');
return 0;
}
int camp(char* name,Class* first)
{
Class* pcurrent=first;
int i=0;
int b=0;
while(pcurrent!=NULL) //在班级链表循环里比较输入的学生名字是否在班级里
{
for(b=0;b<pcurrent->student_number;b++) //用循环遍历一个班级的所有学生跟输入学生作比较
{
if(strcmp(name,pcurrent->student[b]->name)==0) //如果有的话就输出这个学生的成绩
{
printf("%s在%s\n",pcurrent->student[b]->name,pcurrent->class_name);
for(i=0;i<SUB;i++)
{
switch(i)
{
case 0:
printf("%s的语文成绩为%.2lf ",pcurrent->student[b]->name,pcurrent->student[b]->subject[i]);
break;
case 1:
printf("%s的数学成绩为%.2lf ",pcurrent->student[b]->name,pcurrent->student[b]->subject[i]);
break;
case 2:
printf("%s的英语成绩为%.2lf\n",pcurrent->student[b]->name,pcurrent->student[b]->subject[i]);
break;
default:
break;
}
}
return 1;
}
}
pcurrent=pcurrent->pnext;
}
return 0;
}