www.pudn.com > studentscore.rar > studentscore.cpp, change:2007-07-16,size:14343b
#include "stdafx.h"//c++必须的文件.
#include <stdlib.h>
#include <string.h>//字符串操作时会用到
#include <conio.h>//文件操作会用到.
#include "iostream.h"//c++里面的cin.cout的包含文件
#include "Link.h"//link类的声明文件
#include "File.h"//file类的文件声明文件
#define COURSENUMBER 30 //学科的数目.一般30个已经够了,如果不够改变这里就行了.
int AddCourse(char subject[][15]) ]);//首先程序会让你去添加科目
int menu();//菜单
extern char str[];
extern int coursenumber;
extern Link *head;//首指针
extern int save;//用来判断是否保存了.
extern char subject[COURSENUMBER][15];//二维数组,用来存贮各门课的名称.最大长度时15个字符.要想再长,可以改变15为更长.即可
Manager.cpp的代码(入口核心);
#include "stdafx.h"
#include "manager.h"
void main()
{
char s;
int count=0,sum,num,score[COURSENUMBER]={0};//.sum时总分,num时学生的学号,score数组是用来存放学生的各门成绩的.
Link p,*pr,*pr2;//定义了三个link类的指针
File q;//定义了一个File对象
int c;//用来得到Menu的返回值
int i;
//coursenumber 由来得到AddCourse函数的返回值即:共有多少科。i是用来循环累加的。
FILE *fp;//定义了文件指针,用来操作文件的.
char name[20],pathname[30];//pathname是用来存放用户输入的保存或导入时的地址.
cout<<"Press 'n' to create new,press 'l' to load"<<endl;//程序一开让用户选择是新建一个.还是导入.
cin>>s;
if(s=='l')//如果是导入,那么就执行下面的代码
{
cout<<"Please input the pathname:"<<endl;
cin>>pathname;
fp=fopen(pathname,"r");
if(fp==NULL)
{
cout<<"Can't open it"<<endl;
getch();
exit(0);
}
head=q.Read(fp,head,subject);
save=1;
goto load;
}
again: //如果是新建的,就执行下面的代码:
if(count==1)//判断科目是否存在
head=p.DelAllStudent(head);//删除所有人的信息.DelAllStudent()是Link类的成员函数.
coursenumber=AddCourse(subject);//AddCourse()是用来添加科目的函数.见下方有源代码体
load:
while(1)
{
c=menu();//menu函数就是显示菜单项目.case里面的1,2,3,4..等都是对应Menu
switch(c)
{
case 1://显示学生的信息
p.DispStudent(head,coursenumber,subject);//用于显示学习信息.代码见后
break;
case 2://写入学生的信息
cout<<"Please input the student's ID and name:"<<endl;
cin>>num>>name; //输入学号,名字
cout<<"Plesae input the student's score!"<<endl;
for(i=0;i<coursenumber;i++) //输出事先写入的科目
{
cout<<subject[i]<<" ";
}
cout<<endl;
for(i=0;i<coursenumber;i++)//输入学生的成绩,与事先输入的科目相对应
cin>>score[i];
sum=0;
for(i=0;i<coursenumber;i++)//计算出学生额总成绩来
{
sum=sum+score[i];
}
if(head==NULL)//建一个学生信息CreateStudent()也是link类的成员函数
{ //首先看看首指针是不是空的,是的话说明没有数据
head=p.CreateStudent(num,name,score,sum,coursenumber);
}
else
{//如果有数据,那就要接着前面的链表连接起来
pr=p.CreateStudent(num,name,score,sum,coursenumber);
head=p.Order(head,pr,sum);
//Order是Link类的成员,用来排列添加了同学的顺序的
}
break;
case 3://删除一个学生的信息
if(head==NULL)//首先判断首指针是不是为空,是的话就说没有可以删除
{
cout<<"Wrong!No students!"<<endl;
break;
}
//如果首指针不是空的.就用输入学号来删除一个学生.
cout<<"please enter the student's number"<<endl;
cin>>num;
head=p.DelStudent(head,num);
break;
case 4://查找一个学生的信息
if(head==NULL) //首先判断首指针是不是为空,是的话就说没有可以查
{
cout<<"Wrong!No students!"<<endl;
break;
}
//如果首指针不是空的,就输入学号进行查询.
cout<<"Please enter the student's ID and to search it"<<endl;
cin>>num;
pr2=p.SearchStudent(head,num);
if(pr2!=NULL)
p.PrintStudent(pr2,subject,coursenumber);
//PrintStudent()是Link类的成员,显示查询出来的学生信息
break;
case 5://修改一个学生的信息
if(head==NULL)//首先看看首指针是否为空
{
cout<<"Wrong!No students!"<<endl;
break;
}
cout<<"Please input the ID"<<endl;
cin>>num;
head=p.ChangeStudent(head,num,subject,coursenumber);
//ChangerStudent()是link类的成员,用来改变学生的信息
break;
case 6://删除所有学生的信息。
if(head==NULL)
{
cout<<"Wrong!No students!"<<endl;
break;
}
head=p.DelAllStudent(head);//Link的成员,删除所以信息
break;
SAVE:
case 7://保存成绩
if(head==NULL)//首先还是一样,看看有没有空首指针
{
cout<<"Wrong!No students!"<<endl;
break;
}
cout<<"Please input the pathname:"<<endl;
cin>>pathname;输入要保存的路径.如:c:\\a\a.txt
fp=fopen(pathname,"w+");//打开文件fopen
if(fp==NULL)//判断文件是否存在
{
cout<<"Can't open it"<<endl;
getch();
break;
}
head=q.SaveFile(fp,head,coursenumber,subject);//SaveFile是File类的成员
fclose(fp);
break;
case 8://用来改变刚刚输入的科目.count变成1,说明以前有科目记录
count=1;
goto again;
case 9://导入学生的成绩
cout<<"Please input the pathname:"<<endl;
cin>>pathname;
fp=fopen(pathname,"r");
if(fp==NULL)
{
cout<<"Can't open it"<<endl;
getch();
exit(0);
}
head=q.Read(fp,head,subject);
break;
case 10://退出
if(save)//判断是否是在退出钱保存的记录.没有给予图示
exit(0);
else
{
cout<<"You have saved it,Do you want to save it? 'y' or 'n'"<<endl;
cin>>s;
if(s=='y')
goto SAVE;
else
exit(0);
}
}
}
}
//添加课程,参数学科数组,返回有多少学科.
int AddCourse(char subject[][15])
{
int i=0;
int coursenumber;
char c;
cout<<"press 'q' to quit,press any key to continue"<<endl;
c=getch();
if(c=='q')
exit(0);
else
{
cout<<"Please input the subject"<<endl;
for(i=0;;i++)
{
coursenumber=i+1;
scanf("%s",subject[i]);
scanf("%c",&c);
if(c=='\n')
break;
}
}
return coursenumber;
}
//菜单,返回选择的菜单项
int menu()
{
int c;
while(1)
{
cout<<"press '1' to display the score"<<endl;//要判断是否存在着学生
cout<<"press '2' to create and add students' information"<<endl;
cout<<"press '3' to delete students' information"<<endl;//要判断是否存在着学生
cout<<"press '4' to Search a students's information"<<endl;//要判断是否存在着学生
cout<<"press '5' to Chang a studnets' information"<<endl;//要判断是否存在着学生
cout<<"press '6' to delete all students' information"<<endl;//要判断是否存在着学生
cout<<"press '7' to save the table"<<endl;
cout<<"press '8' to change the subject"<<endl;
cout<<"press '9' to load"<<endl;
cout<<"press '10' to exit"<<endl;
scanf("%d",&c);
if(c==1 || c==2 || c==3 || c==4 || c==5 || c==6 || c==7 || c==8 ||c==9 ||c==10)
{
return c;
}
else
{
cout<<"Wrong!Plesase input again!"<<endl;
continue;
}
}
}
Link.h的代码:
#include "stdio.h"
#define COURSENUMBER 30
class Link
{
public:
Link();
virtual ~Link();
Link *next;
private:
int score[COURSENUMBER];//各个学科的成绩
char name[20];//姓名
int num; //ID
int sum;//总分
float average;//平均分
static int k;//用来记录链表的个数用静态函数表示
public:
void DispStudent(Link *head,int coursenumber,char subject[][15]);//显示学生的信息
Link *Order(Link *head,Link *p,int sum);//把添加的学生进行排序
Link *DelStudent(Link *head,int num);//删除一个学生的 成绩
Link *CreateStudent(int num,char name[],int score[],int sum,int coursenumber);//创建第一个学生的信息/
Link *SearchStudent(Link *head,int num);//查找一个学生的信息
void PrintStudent(Link *pr2,char subject[][15],int coursenumber);//打印查找出来的一个学生的成绩
Link *ChangeStudent(Link *head,int num,char subject[][15],int coursenumber);//修改一个学生成绩
Link *DelAllStudent(Link *head);//删除所有 的学生的成绩
public://接口
int getnum(){return num;}
int getsum(){return sum;}
float getaverage(){return average;}
char *getname(){return name;}
int *getscore(){return score;}
};
Link.cpp源程序:
#include "stdafx.h"
#include "manager.h"
char str[]=" sum average ID name ";
int coursenumber;
Link *head;//头指针
int save=0;//用来记录文件是否保存
int cnum;//用来判断链表是否存在,在changestudent中有用
int Link::k=0;//用来记录链表的个数
char subject[COURSENUMBER][15];
Link::Link()//构造函数
{
}
Link::~Link()
{
}
//显示学生的链表
//参数:头指针,科目数目,科目内容。
void Link::DispStudent(Link *head,int coursenumber,char subject[][15])
{
Link *p;
int i=0;
if(head==NULL)
{
cout<<"Wrong! you need to add at least one student!Empty!"<<endl;
}
else
{
p=head;
for(i=0;i<coursenumber;i++)
{
cout<<" "<<subject[i]<<" ";
}
cout<<str<<endl;
do{
for(i=0;i<coursenumber;i++)
printf("%6d",p->score[i]);
printf("%6d%8.2f%15d%20s\n",p->sum,p->average,p->num,p->name);
p=p->next;
}while(p!=NULL);
}
}
//建立第一个链表。即:建立第一个同学的信息。
//参数:学生ID,姓名,分数,总和,科目的分数;返回创建学生的新的地址
Link *Link::CreateStudent(int num,char name[],int score[],int sum,int coursenumber)
{
int i;
Link *p;
p=new Link;//用new比用malloc好用的多了。
if(p==NULL)
{
cout<<"Wrong!No enough memory!"<<endl;
exit(0);
}
p->next=NULL;
p->num=num;
for(i=0;i<coursenumber;i++)
p->score[i]=score[i];
strcpy(p->name,name);
p->sum=sum;
p->average=(float)sum/coursenumber;
cout<<"The Studnet have been create!"<<endl;
k++;
return p;
}
//把添加的学生进行排序
//参数:头指针,创建新学生的指针,总分,返回头指针
Link *Link::Order(Link *head,Link *p,int sum)
{
if(head==NULL)
{
return p;
}
Link *pr,*pr2;//pr2是用来存放pr的地址,然后pr可以向后移。
pr=head;
if(k==1)
return head;
if(k==2)//判断是不是只存在一个同学,k=2时说明只存在一个同学,2说明的是创建了第二个还没有插进去。
{
if(pr->sum<sum)
{
p->next=head;
head=p;
return head;
}
if(pr->sum>=sum)
pr->next=p;
}
else//下面的是:不是一个学生的时候
{
while(pr->sum>sum && pr->next!=NULL)
{
pr2=pr;
pr=pr->next;
}
if(pr==head)
{
p->next=head;
head=p;
return head;
}
if(pr->next==NULL)
{
if(pr->sum>sum)
pr->next=p;
else
{
p->next=pr2->next;
pr2->next=p;
}
}
else
{
p->next=pr2->next;
pr2->next=p;
}
}
return head;
}
//删除学生
//参数是学生的学号.返回头指针
Link *Link::DelStudent(Link *head,int num)
{
Link *p,*pr;
if(head==NULL)
{
cout<<"No students exist"<<endl;
return head;
}
p=head;
while(p->num!=num && p->next!=NULL)
{
pr=p;
p=p->next;
}
if(p->num==num)
{
if(p==head)
{
head=p->next;
delete p;
cout<<"Delete the Student"<<endl;
}
else
{
pr->next=p->next;
delete p;
cout<<"Delete the Student"<<endl;
}
k--;//删除一个链表也就减少一个
save=0;//要求重新保存,因为修改过了
cnum=0;
}
else
{
cout<<"Can't not find it ,it is not exist!"<<endl;
cnum=1;
}
return head;
}
//查找一个学生的信息。
//参数:头指针,学生学号,返回查找到了的指针
Link *Link::SearchStudent(Link *head,int num)
{
Link *pr;
pr=head;
while(pr->num!=num)
{
pr=pr->next;
if(pr==NULL)
{
cout<<"Wrong!The students is not exist"<<endl;
return NULL;
break;
}
}
return pr;
}
//打印搜索到的学生信息
//参数:要显示学生的Link指针,学生的科目,和科目数目.无返回值
void Link::PrintStudent(Link *pr2,char subject[][15],int coursenumber)
{
int i;
for(i=0;i<coursenumber;i++)
{
cout<<" "<<subject[i]<<" ";
}
cout<<str<<endl;
for(i=0;i<coursenumber;i++)
printf("%6d",pr2->score[i]);
printf("%6d%8.2f%15d%20s\n",pr2->sum,pr2->average,pr2->num,pr2->name);
}
//删除所有人的信息
//参数:头指针,返回NULL值
Link *Link::DelAllStudent(Link *head)
{
Link *pr,*pr2;
pr=head;
do
{
pr2=pr;
pr=pr->next;
delete pr2;
}while(pr!=NULL);
save=0;//所以删除后要变成假,以便再次输入后退出的时候确认是否要保存
k=0;//链表数目也就变成0
return NULL;
}
//修改一个学生的信息。
//参数:头指针,学号,科目名,科目数;返回头指针.
Link* Link::ChangeStudent(Link *head,int num,char subject[][15],int coursenumber)
{
int i;
Link *pr;
int num2,score[COURSENUMBER],sum=0;
char name[20];
head=DelStudent(head,num);//首先删除一个同学的信息,下面再去创建。
//不能直接去修改,这样的化就会有顺序不对的情况,分数就没有重新排列
if(cnum)
{
cout<<"Wrong!No ID!"<<endl;
return head;
}
cout<<"Please enter the new information:"<<endl;
cout<<"Please enter the ID and name"<<endl;
cin>>num2>>name;
cout<<"Please input the score!"<<endl;
for(i=0;i<coursenumber;i++)
{
cout<<" "<<subject[i]<<" ";
}
cout<<endl;
for(i=0;i<coursenumber;i++)
cin>>score[i];
sum=0;
for(i=0;i<coursenumber;i++)
sum=sum+score[i];
pr=CreateStudent(num2,name,score,sum,coursenumber);
head=Order(head,pr,sum);
cout<<"The student has been change press '1' to check"<<endl;
return head;
}
File.h文件:
#include "manager.h"
class File
{
public:
File();
virtual ~File();
public:
Link *SaveFile(FILE *fp,Link *head,int coursenumber,char subject[][15]);//保存文件函数
Link *File::Read(FILE *fp,Link *head,char subject[][15]);//读取文件函数
};
File.cpp文件:
#include "stdafx.h"
#include "manager.h"
File::File()
{}
File::~File()
{}
//保存表单
Link *File::SaveFile(FILE *fp,Link *head,int coursenumber,char subject[][15])
{
Link *pr;
int *sco;
int i;
pr=head;
do
{
sco=pr->getscore();
for(i=0;i<coursenumber;i++)
{
fprintf(fp,"**%s ",subject[i]);
fprintf(fp,"%d",sco[i]);
}
fprintf(fp," %d %.2f %d %s",pr->getsum(),pr->getaverage(),pr->getnum(),pr->getname());
fprintf(fp,"\n");
pr=pr->next;
}while(pr!=NULL);
fprintf(fp,"q");
save=1;//保存后save变成0
return head;
}
//倒入表单
Link *File::Read(FILE *fp,Link *head,char subject[][15])
{
Link q;
Link *p;
int coursenumbers=0,score[COURSENUMBER],i,sum,num;
char name[20];
char c;
float average;
if(head!=NULL)
head=q.DelAllStudent(head);//这样链表就被清空了,实际上是要先保存再清空,要给用户提示,但是在这儿就不写了
while(1)
{
for(i=0;;i++)
{
fscanf(fp,"%c",&c);
if(c==' ')
break;
coursenumbers++;
fscanf(fp,"%s %d",subject[i],&score[i]);
}
coursenumber=coursenumbers;
fscanf(fp,"%d %f %d %s",&sum,&average,&num,name);
p=q.CreateStudent(num,name,score,sum,coursenumbers);
head=q.Order(head,p,sum);
fscanf(fp,"%1s",&c);
if(c=='q')
break;
coursenumbers=0;
}
return head;
}