#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
FILE *fstu;//指向学生信息表文件的指针
FILE *fgra;//指向成绩的指针
struct stu_f//学生基本表
{
char student_number[20];
char student_name[30];
char genden[10];
char major[50];
char college[50];
double GPA;
stu_f* next;
} ;
struct gra_f//学生成绩表
{
char student_number[20];
char course_number[20];
char course_name[40];
int credit;
int score;
gra_f* next;
} ;
//部分函数的申明
double get_GPA(char * number);
stu_f *head_stu;
gra_f *head_gra;
FILE * save_gra(gra_f *head);
gra_f* delete_gra(gra_f*head,char * a);
gra_f* reopen_gra(FILE * fgra);
gra_f* search_gra_number(gra_f*head,char * a);
stu_f* search_stu_number(stu_f*head,char * a);
//函数的定义
double get_GPA(char * number)//根据学生成绩求出其绩点
{
double GPA =0;
int total_score=0;
int total_credit=0;
gra_f*p;
if((fgra=fopen("score_data.txt","rb+"))==NULL)
return 0 ;
p=reopen_gra(fgra);
fclose(fgra);
while(search_gra_number(p,number)!=NULL)
{
p=search_gra_number(p,number)->next;
total_score+=p->score*p->credit;
total_credit+=p->credit;
}
GPA=total_score*1.0/total_credit/100*5;
return GPA;
}
void creat_student_form(FILE*fstu)//创建新的学生表
{
stu_f*p;
int exit=1;
while(exit)
{
p=new stu_f;
cout<<"请输入学号:";
cin>>p->student_number;//输入信息
cout<<"请输入姓名:";
cin>>p->student_name;
cout<<"请输入性别(男,女):";
cin>>p->genden;
cout<<"请输入所在专业:";
cin>>p->major;
cout<<"请输入所在学院:";
cin>>p->college;
//p->GPA=get_GPA(p->student_number);
fwrite(p,sizeof(struct stu_f),1,fstu);
cout<<"是否继续输入(1:是,0:否)";
cin>>exit;
while(exit!=1&&exit!=0)
{
cout<<"非法输入"<<endl;
cout<<"是否继续输入(1:是,0:否)";
cin>>exit;
}
}
rewind(fstu);
fclose(fstu);
return ;
}
stu_f* reopen_stu(FILE * fstu)//根据文件建立链表,并按学号递增顺序排列,返回头指针
{
stu_f *p, *tail, *head, *insert;
p=new stu_f;
head=p;
head->next =NULL;
insert = new stu_f;
while(fread(insert,sizeof(struct stu_f),1,fstu))
{
tail=head;//指向需要判断的节点前一个节点的指针
p = head->next ;
while(p!=NULL)
{
if(strcmp(insert->student_number,p->student_number)==-1)
{
tail->next =insert;
insert->next =p;
break;
}
p=p->next ;
tail=tail->next;
}
if(p==NULL/*&&strcmp(insert->student_number ,tail->student_number )!=0*/)
{
p=insert;
tail->next =p;
p->next =NULL;
}
insert=new stu_f;
}
rewind(fstu);
return head;
}
void print_stu(stu_f *p)//输出链表中的内容
{
stu_f* m=p->next;
cout<<"学号"<<"\t"
<<"姓名"<<"\t"
<<"性别"<<"\t"
<<"专业"<<"\t"
<<"GPA"<< "\t"
<<"学院"<<endl;
while(m!=NULL)
{
cout<<m->student_number<<"\t"
<<m->student_name<<"\t"
<<m->genden<<"\t"
<<m->major<<"\t"
<<get_GPA(m->student_number)<<"\t"
<<m->college<<endl;
//<<GPA;;
m=m->next;
}
return;
}
void print_GPA(stu_f *p)//输出链表中的内容
{
stu_f* m=p->next;
cout<<"学号"<<"\t"
<<"姓名"<<"\t"
<<"GPA"<< "\t"
<<endl;
while(m!=NULL)
{
cout<<m->student_number<<"\t"
<<m->student_name<<"\t"
<<get_GPA(m->student_number)<<"\t"
<<endl;
m=m->next;
}
return;
}
stu_f* add_stu(stu_f *head)//在链表中按学号插入元素
{
stu_f*save;
int exit=1;
while(exit)
{
save=new stu_f;
cout<<"请输入学号:";
cin>>save->student_number;
if(search_stu_number(head,save->student_number)!=NULL)
{
cout<<"该学号已存在。";
break;
}
while(save->student_number[7]!='\0')
{
cout<<"非法输入"<<endl;
cout<<"请输入学号:";
cin>>save->student_number;
}
cout<<"请输入姓名:";
cin>>save->student_name;
cout<<"请输入性别(男,女):";
cin>>save->genden;
cout<<"请输入所在专业:";
cin>>save->major;
cout<<"请输入所在学院:";
cin>>save->college; //输入信息
stu_f *tail, *p;
tail=head;//指向需要判断的节点前一个节点的指针
p = head->next ;
while(p!=NULL)
{
if(strcmp(save->student_number,p->student_number)==-1)
{
tail->next =save;
save->next =p;
break;
}
p=p->next ;
tail=tail->next;
}
if(p==NULL)
{
p=save;
tail->next =p;
p->next =NULL;
}
cout<<"是否继续输入(1:是,0:否)";
cin>>exit;
while(exit!=1&&exit!=0)
{
cout<<"非法输入"<<endl;
cout<<"是否继续输入(1:是,0:否)";
cin>>exit;
}
}
return head;
}
FILE * save_stu(stu_f *head)//将链表保存在文件中
{
FILE*fstu;
remove("student_data.txt");
fstu=fopen("student_data.txt","wb+");
stu_f* m=head->next;
rewind(fstu);
while(m!=NULL)
{
fwrite(m,sizeof(struct stu_f),1,fstu);
m=m->next;
}
rewind(fstu);
fclose(fstu);
return fstu;
}
stu_f* search_stu_number(stu_f*head,char * a)//按学号搜索,返回其前置指针,未找到时返回NULL
{
stu_f*p=head;
stu_f*m=p->next;
while(m !=NULL)
{
if(strcmp(m->student_number,a)==0)
return p;
p=p->next ;
m=p->next ;
}
return NULL;
}
stu_f* delete_stu(stu_f*head,char * a)//按学号删除
{
stu_f* tail,*p;
tail=search_stu_number(head,a);
if(tail==NULL)
{
cout<<"查无此人,删除失败"<<endl;
return head;
}
p=tail->next ;
tail->next =p->next ;
delete p;
if((fgra=fopen("score_data.txt","rb+"))!=NULL)
{
head_gra=reopen_gra(fgra);
head_gra=delete_gra(head_gra,a);
fgra=save_gra(head_gra);
}
cout<<"删除成功"<<endl;
return head;
}
int creat_gra_form(FILE*fgra)//创建新的课程表
{
gra_f*p;
if((fstu=fopen("student_data.txt","rb+"))==NULL)
{
return 0;
}
int exit=1;
while(exit)
{
p=new gra_f;
cout<<"请输入学号:";
cin>>p->student_number;
if((fstu=fopen("student_data.txt","rb+"))==NULL)
{
return 0;
}
head_stu=reopen_stu(fstu);
fclose(fstu);
while(search_stu_number(head_stu, p->student_number)==NULL)
{
int k;
cout<<"该学生不存在,是否重新输入(1:是,0:否)";
cin>>k;
while(k!=1&&k!=0)
{
cout<<"非法输入"<<endl;
cout<<"是否继续输入(1:是,0:否)";
cin>>k;
}
if(!k)
break;
cout<<"请输入学号:";
cin>>p->student_number;
}
if(search_stu_number(head_stu, p->student_number)==NULL)
break;
cout<<"请输入课程号:";
cin>>p->course_number;
cout<<"请输入课程名称:";
cin>>p->course_name;
cout<<"请输入课程学分:";
cin>>p->credit;
cout<<"请输入成绩:";
cin>>p->score;
fwrite(p,sizeof(struct gra_f),1,fgra);
cout<<"是否继续输入(1:是,0:否)";
cin>>exit;
while(exit!=1&&exit!=0)
{
cout<<"非法输入"<<endl;
cout<<"是否继续输入(1:是,0:否)";
cin>>exit;
}
}
rewind(fgra);
fclose(fgra);
return 1;
}
gra_f* reopen_gra(FILE * fgra)//根据文件建立链表,并按学号递增顺序排列,返回头指针
{
gra_f *p, *tail, *head, *insert;
p=new gra_f;
head=p;
head->next =NULL;
insert = new gra_f;
while(fread(insert,sizeof(struct gra_f),1,fgra))
{
tail=head;//指向需要判断的节点前一个节点的指针
p = head->next ;
while(p!=NULL)
{
if(strcmp(insert->student_number,p->student_number)==-1)
{
tail->next =insert;
insert->next =p;
break;
}
p=p->next ;
tail=tail->next;
}
if(p==NULL/*&&strcmp(insert->student_number ,tail->student_number )!=0*/)
{
p=insert;
tail->next =p;
p->next =NULL;
}
insert=new gra_f;
}
rewind(fgra);
return head;
}
void print_gra(gra_f *p)//输出链表中的内容
{
gra_f* m=p->next;
cout<<"学号"<<"\t"
<<"课程号"<<"\t"
<<"课程名"<<"\t"
<<"学分"<<"\t"
<<"成绩"<<endl;
while(m!=NULL)
{
cout<<m->student_number<<"\t"
<<m->course_number<<"\t"
<<m->course_name<<"\t"
<<m->credit<<"\t"
<<m->score<<endl;
m=m->next;
}
return;
}
gra_f* add_gra(gra_f *head)//在链表中按学号插入元素
{
gra_f*save;
int exit=1;
while(exit)
{
save=new gra_f;
cout<<"请输入学号:";
cin>>save->student_number;
head_stu=NULL;
if((fstu=fopen("student_data.txt","rb+"))!=NULL)
head_stu=reopen_stu(fstu);
fclose(fstu);
while((save->student_number[7]!='\0')||search_stu_number(head_stu, save->student_number)==NULL)
{
int k;
cout<<"该学生不存在,是否重新输入(1:是,0:否)";
cin>>k;
while(k!=1&&k!=0)
{
cout<<"非法输入"<<endl;
cout<<"是否继续输入(1:是,0:否)";
cin>>k;
}
if(!k)
return head;
cout<<"请输入学号:";
cin>>save->student_number;
}
cout<<"请输入课程号:";
cin>>save->course_number;
cout<<"请输入课程名称:";
cin>>save->course_name;
cout<<"请输入课程学分:";
cin>>save->credit;
cout<<"请输入成绩:";
cin>>save->score;
gra_f *tail, *p;
tail=head;//指向需要判断的节点前一个节点的指针
p = head->next ;
while(p!=NULL)
{
if(strcmp(save->student_number,p->student_number)==-1)
{
tail->next =save;
save->next =p;
break;
}
p=p->next ;
tail=tail->next;
}
if(p==NULL)
{
p=save;
tail->next =p;
p->next =NULL;
}
cout<<"是否继续输入(1:是,0:否)";
cin>>exit;
while(exit!=1&&exit!=0)
{
cout<<"非法输入"<<endl;
cout<<"是否继续输入(1:是,0:否)";
cin>>exit;
}
}
return head;
}
FILE * save_gra(gra_f *head)//将链表保存在文件中
{
FILE*fgra;
remove("score_data.txt");
fgra=fopen("score_data.txt","wb+");
gra_f* m=head->next;
rewind(fgra);
while(m!=NULL)
{
fwrite(m,sizeof(struct gra_f),1,fgra);
m=m->next;
}
rewind(fgra);
fclose(fgra);
return fgra;
}
gra_f* search_gra_number(gra_f*head,char * a)//按学号搜索,返回其前置指针,未找到时返回NULL
{
gra_f*p=head;
gra_f*m=p->next;
while(m !=NULL)
{
if(strcmp(m->student_number,a)==0)
return p;
p=p->next ;
m=p->next ;
}
return NULL;
}
gra_f* delete_gra(gra_f*head,char * a)//按学号删除
{
gra_f* tail,*p;
tail=search_gra_number(head,a);
if(tail==NULL)
{
cout<<"删除结束"<<endl;
return head;
}
p=tail->next ;
tail->next =p->next ;
delete p;
return delete_gra(head,a);
}
stu_f* search_stu_courage(stu_f* insert,char* major)//查找从insert开始某专业的第一个学生信息,返回该指针
{
stu_f*p=insert;
p=p->next;
while(p!=NULL)
{
if(strcmp(p->major,major)==0)
return p;
p=p->next ;
}
return NULL;
}
int main()
{
while(1)
{
cout<<"欢迎使用学生管理系统,请输入您需要的功能:"<<endl;
cout<<"1:打开学生信息表。 2:打开学生成绩表。3:查询学生情况。4:查询专业排名。0:退出。"<<endl;
int control;//记录输入,选择功能
cin>>control;
switch(control)
{
case 1:
{
if((fstu=fopen("student_data.txt","rb+"))==NULL)
{
cout<<"未找到学生信息表,请开始创建"<<endl;
fstu=fopen("student_data.txt","wb+");
creat_student_form(fstu);//创建链表,保存在fstu指向的文件中
fstu=fopen("student_data.txt","rb+");
}
head_stu=reopen_stu(fstu);//根据文件中的信息重建链表
cout<<"已加载信息表,请选择功能"<<endl;
int control=1;
while(control)
{
cout<<"1:显示信息表。2:添加学生记录。3:按学号删除学生记录。4:按学号查询。0:保存并退出。";
cin>>control;
switch(control)
{
case 1:
print_stu(head_stu);
break;
case 2:
head_stu=add_stu(head_stu);
break;
case 3:
char a[10];
cout<<"请输入要删除的学生学号:"<<endl;
cin>>a;
head_stu=delete_stu(head_stu,a);
break;
case 4:
break;
case 0:
fstu=save_stu(head_stu);
break;
default:
cout<<"输入错误,请重新输入 "<<endl;
break;
}
}
}
break;
case 2:
{
if((fgra=fopen("score_data.txt","rb+"))==NULL)
{
cout<<"未找到学生信息表,请开始创建"<<endl;
if((fstu=fopen("student_data.txt","rb+"))==NULL)
{
break;
}
fgra=fopen("score_data.txt","wb+");
if(!creat_gra_form(fgra));//创建链表,保存在fstu指向的文件中
break;
fgra=fopen("score_data.txt","rb+");
}
head_gra=reopen_gra(fgra);//根据文件中的信息重建链表
cout<<"已加载信息表,请选择功能"<<endl;
int control=1;
while(control)
{
cout<<"1:显示信息表。2:添加学生记录。3:按学号删除学生成绩。0:保存并退出。";
cin>>control;
switch(control)
{
case 1:
print_gra(head_gra);
break;
case 2:
head_gra=add_gra(head_gra);
break;
case 3:
char a[10];
cout<<"请输入要删除的学生学号:"<<endl;
cin>>a;
head_gra=delete_gra(head_gra,a);
break;
case 4:
break;
case 0:
fgra=save_gra(head_gra);
break;
default:
cout<<"输入错误,请重新输入 "<<endl;
break;
}
}
}
break;
case 3:
{
if((fstu=fopen("student_data.txt","rb+"))==NULL)
{
cout<<"未找到学生信息表"<<endl;
fclose(fstu);
break;
}
head_stu=reopen_stu(fstu);
fclose(fstu);
stu_f*p;
cout<<"请输入学号:";
char search_number[20];
cin>>search_number;//输入信息
if((p=search_stu_number(head_stu,search_number))==NULL)
{
cout<<"输入的学号不存在"<<endl;
break;
}
p=p->next;
int c=1;
while(c!=0)
{
cout<<"请输入查询内容:(1:姓名。2:所在系。3:平均绩点。4:已经修学分。0:结束)";
cin>>c;
switch (c)
{
case 1:
cout<<p->student_name<<endl<<endl;
break;
case 2:
cout<<p->college<<endl<<endl;
break;
case 3:
cout<<p->GPA<<endl;
break;
case 4:
{
int total_credit=0;
gra_f*m;
if((fgra=fopen("score_data.txt","rb+"))!=NULL)
{
m=reopen_gra(fgra);
fclose(fgra);
while(search_gra_number(m,search_number)!=NULL)
{
m=search_gra_number(m,search_number)->next;
total_credit+=m->credit;
}
}
cout<<total_credit<<endl;
}
break;
case 0:
break;
default:
cout<<"输入非法,请重新输入"<<endl;
break;
}
}
}
break;
case 4:
{
char major[50];
double total_GPA=0;
int n=0;//学生人数
cout<<"请输入专业名称进行查询:"<<endl;
cin>>major;
stu_f *p, *tail, *head, *insert,*find;
p=new stu_f;
head=p;
head->next =NULL;
if((fstu=fopen("student_data.txt","rb+"))==NULL)
{
cout<<"未找到学生信息表"<<endl;
fclose(fstu);
break;
}
insert=reopen_stu(fstu);
fclose(fstu);
insert = search_stu_courage(insert,major);
find=new stu_f;
strcpy(find->student_number,insert->student_number);
strcpy(find->student_name ,insert->student_name);
find->GPA = get_GPA(insert->student_number );
find->next =NULL;
while(insert!=NULL)
{
tail=head;//指向需要判断的节点前一个节点的指针
p = head->next ;
while(p!=NULL)
{
p->GPA =get_GPA(p->student_number );
if((find->GPA)>(p->GPA))
{
tail->next =find;
find->next =p;
n++;
total_GPA+=find->GPA ;
break;
}
p=p->next ;
tail=tail->next;
}
if(p ==NULL)
{
p=find;
tail->next =p;
p->next =NULL;
n++;
total_GPA+=find->GPA ;
}
find=new stu_f;
insert = search_stu_courage(insert,major);
if(insert==NULL)
break;
strcpy(find->student_number,insert->student_number);
strcpy(find->student_name ,insert->student_name);
find->GPA = get_GPA(insert->student_number );
find->next = NULL;
}
print_GPA(head);
cout<<"平均绩点 :"<<total_GPA*1.0/n<<endl;
}
break;
case 0:
return 0;
break;
default:
cout<<"输入错误,请重新输入 "<<endl;
break;
}
}
return 0;
}
c++实现,运用链表