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; 
}