学籍管理系统(c++实训二)

学籍管理系统(双链表、模版实现)

刚完成了复数计算器这个项目,怀着激动的心情开始第二个项目学籍管理系统,这个项目用到了双链表和模版的知识。用双链表的目的是为了能实现从首部插入和删除学生信息以及从尾部插入删除学生信息。用模版是为了更方便的修改数据。

写代码思路
在这里插入图片描述

程序分析

该项目最重要的是要用到双链表的知识,以及学生类中的运算符重载。双链表可以实现对数据进行插入删除等操作,是程序的核心。而学生类中运算符重载是为了使双链表能够对学生类进行操作,模版正是这个中间条件。

代码

mian.cpp

#include <iostream>
#include "information.h"
#include "class.h" 
#include<string>
using namespace std;
int main()
{
	DoubleLinkList <Information> List;
 	int Option;
	Information Value;
 	do 
	{
		cout<<"\n学籍管理系统"
	    <<"\n-------------------------"
		<<"\n1.在首部插入一个学生信息。"
        <<"\n2.在尾部插入一个学生信息。"
        <<"\n3.从首部删除一个学生信息。"
        <<"\n4.从尾部删除一个学生信息。"
        <<"\n5.从首部输出学生信息。"
        <<"\n6.从尾部输出学生信息。"
        <<"\n7.按姓名查找学生。"
        <<"\n8.按学号查找学生"
        <<"\n9.将学生信息按学号从小到大排序。"
        <<"\n10.将学生信息按分数从高到低排序。"
        <<"\n11.将学生信息存入指定文件中。"
        <<"\n12.读取指定文件中的学生信息。"
		<<"\n0.退出。"
		<<"\n------------------------"
		<<"\n输入您的选择:";
 		cin>>Option;
 		switch(Option)
 		{ 
 	
			case 1:
 			{
				cout<<"\n";
  				cin>>Value;
  				List.inserart_At_Front(Value);
  				system("pause");
				system("cls");
  				break;
  			
 			}
 			case 2:
	 		{ 
	 			cout<<"\n";
	    		cin>>Value;
	    		List.inserart_At_Rear(Value);
	   			system("pause");
				system("cls");
				break;
	 		}
 			case 3:
	 		{ 
	 			List.Remove_From_Front();
	    		system("pause");
				system("cls");
				break;
	 		}
 			case 4:
		 	{ 
	   			List.Remove_From_Rear();
	   			system("pause");
				system("cls");
				break;
     		}
 			case 5:
	 			{ 
					List.Traverse_Forward();
	    			system("pause");
					system("cls");
  					break;
	 			}
			case 6:
	 			{ 
	 				List.Tracerse_Backward();
	    			system("pause");
					system("cls");
					break;
    		 	}
    		case 12:
    			{
    				List.Read_File();
    				system("pause");
					system("cls");
					break;
				}
			case 11:
				{
					List.Write_file();
					system("pause");
					system("cls");
					break;
				}
    	
			case 9:
    			{
    				List.Sort_Data_By_Id();
					system("pause");
					system("cls");
					break;	
				}
			case 10:
				{
					List.Sort_Data_By_Score();
					system("pause");
					system("cls");
					break;
				}
			case 7:
				{
					string p;
					cout<<"请输入你要查询的学生姓名:";
					cin>>p;
					List.Search_According_Name(p);
					system("pause");
					system("cls");
					break;
				}
			case 8:
				{
					string n;
					cout<<"请输入你要查询的学生学号:";
					cin>>n;
					List.Search_According_Id(n);
					system("pause");
					system("cls");
					break;
				}
    			
 			default:
	 		{ 
	 			Option=0;
	    		break;
			}
 		}
 	}
 	while(Option!=0);
 	return 0;
}

information.h

#include<iostream>
#include<fstream>
#include<string>
using namespace std;
class Information
{
	friend ostream& operator<<(ostream& output, Information& Target);//输出流重载 
	
	friend istream& operator>>(istream& input, Information& Target);//输入流重载 
	
	friend ofstream& operator<<(ofstream& output, Information& Target); //文件输入流 
	
	friend ifstream& operator>>(ifstream& input, Information& Target);//文件输出流 
	
	friend bool operator ==(Information, string);
public:
	Information();
	Information(Information&);
	~Information();
	operator float();
	operator double();
	string Name;
	string Address;
	string Id;
	string Score;
	string Sex;
};

Information::Information() :Name("\0"), Address("\0"), Id("\0"), Score("\0"), Sex("\0"){}

Information::Information(Information& Value)
{
	Address = Value.Address;
	Id = Value.Id;
	Name = Value.Name;
	Score = Value.Score;
	Sex = Value.Sex;
}

Information::~Information(){}

Information::operator float()
{
	float Temp = 0;
	for (int i = 0; Score[i]; i++)
	{
		Temp *= 10;
		Temp += (Score[i] - '0');
	}
	return Temp;
}

Information::operator double()
{
	double Temp = 0;
	for (int i = 0; Id[i]; i++)
	{
		Temp *= 10;
		Temp += (Id[i] - '0');
	}
	return Temp;
}


bool operator ==(Information stu, string Name)//重载等号运算符,便于查找 
{
	if (stu.Name == Name || stu.Id == Name)
		return true;
	return false;
}

ostream& operator<<(ostream& output, Information& Target)
	{
		output << "姓名:" << Target.Name << endl;
		output << "地址:" << Target.Address << endl;
		output << "学号:" << Target.Id << endl;
		output << "成绩:" << Target.Score << endl;
		output << "性别:" << Target.Sex << endl;
		return output;
	}
istream& operator>>(istream& input, Information& Target)
	{
		cout << "姓名:"; input >> Target.Name;
		cout << "地址:"; input >> Target.Address;
		cout << "学号:"; input >> Target.Id;
		cout << "成绩:"; input >> Target.Score;
		cout << "性别:"; input >> Target.Sex;
		return input;
	}
ofstream& operator<<(ofstream& output, Information& Target)//重载文件输出流
	{
		output << Target.Name << endl;
		output<< Target.Address << endl;
		output<< Target.Id << endl;
		output << Target.Score << endl;
		output <<Target.Sex << endl;
		return output;
	}
ifstream& operator>>(ifstream& input, Information& Target)//重载文件输入流 
	{
		input >> Target.Name;
		input >> Target.Address;
		input >> Target.Id;
		input >> Target.Score;
		input >> Target.Sex;
		return input;
	}

class.h

#include <iostream>
#include <cassert>
#include <string>
#include <fstream>
using namespace std;
template <class NodeType>class Node;
template <class NodeType>class DoubleLinkList;
template <class NodeType>
class Node
{
	private:
		friend class DoubleLinkList<NodeType>;//双链表是节点的友元 
		friend ostream& operator<<(ostream&,NodeType&);
		friend istream& operator<<(istream&,NodeType&);
	public:
		Node();
		Node(NodeType&);
		~Node();
		NodeType Data;//数据域 
		Node<NodeType>* NextNode;//右指针 
		Node<NodeType>* PreviousNode;//左指针	
};
template<class NodeType>
ostream& operator<<(ostream& output,Node<NodeType>& Target)
{
	output<<Target.Data;
	return output;
}
template <class NodeType>
istream& operator<<(istream& input,Node<NodeType>& Target)
{
	input>>Target.Data;
	return input;
}
template <class NodeType>
Node<NodeType>::Node():Data(),NextNode(NULL),PreviousNode(NULL)//结点的无参构造函数 
{
}
template <class NodeType>
Node<NodeType>::Node(NodeType &Value)//结点的有参构造函数 
{
	Data=Value;
	NextNode=NULL;
	PreviousNode=NULL;
}
template <class NodeType>
Node<NodeType>::~Node()//结点的析构函数 
{
}
template <class NodeType>
class DoubleLinkList
{
	public:
		DoubleLinkList();
		~DoubleLinkList();
		bool isEmpty();
		void inserart_At_Front(NodeType &Value);//头部插入 
		void inserart_At_Rear(NodeType &Value);//尾部插入 
		bool Remove_From_Front();
		bool Remove_From_Rear();
		void Traverse_Forward();//从头部遍历 
		void Tracerse_Backward();//从尾部遍历 
		int Lenth_of_DoubleLinkList();//得到双链表的长度 
		Node<NodeType> *CreateNode(NodeType &Value);//创建一个双链表 
		void Sort_Data_By_Id();//按学号排序 
		void Sort_Data_By_Score();//按分数排序 
		void Read_File();//读文件 
		void Write_file();//写文件 
		void Search_According_Name(string n);//按名字查询 
		void Search_According_Id(string p);//按学号查询 
	private:
		Node<NodeType>* FirstNode;
		Node<NodeType>* RearNode;	 
};
template <class NodeType>
DoubleLinkList<NodeType>::DoubleLinkList():FirstNode(NULL),RearNode(NULL)//双链表的无参构造函数
{
}
template <class NodeType>
DoubleLinkList<NodeType>::~DoubleLinkList()//双链表的析构函数 
{
	Node<NodeType> *CurrentNode=FirstNode,*TempNode;
	while(CurrentNode!=NULL)
	{
		TempNode=CurrentNode;
		CurrentNode=CurrentNode->NextNode;
		delete TempNode;
	}

}
template <class NodeType>
bool DoubleLinkList<NodeType>::isEmpty()//判断链表是否为空 
{
	if(FirstNode==NULL)
	{
		cout<<"这是第一位学生的信息"<<endl;
		return true;
	}
	else
	return false;
}
template <class NodeType>
Node <NodeType>*DoubleLinkList<NodeType>::CreateNode(NodeType &Value)//创建一个链表 
{
	Node<NodeType> *NewNode=new Node<NodeType>(Value);
	assert(NewNode!=NULL);
	return NewNode;	
}
template <class NodeType>
void DoubleLinkList<NodeType>::inserart_At_Front(NodeType &Value)//头插法 
{
	Node<NodeType> *NewNode=CreateNode(Value);
	if(isEmpty())
		FirstNode=RearNode=NewNode;
	else
		{
			FirstNode->PreviousNode=NewNode;
			NewNode->NextNode=FirstNode;
			FirstNode=NewNode;
			FirstNode->PreviousNode=NULL;
		}
	//cout<<FirstNode->Data;
	cout<<"\n结点插入成功"<<endl;
	
}
template <class NodeType>
void DoubleLinkList<NodeType>::inserart_At_Rear(NodeType &Value)//尾插法 
{
	Node<NodeType> *NewNode=CreateNode(Value);
	if(isEmpty())
		FirstNode=RearNode=NewNode;
	else
		{
			RearNode->NextNode=NewNode;
			NewNode->PreviousNode=RearNode;
			RearNode=NewNode;
			RearNode->NextNode=NULL;
		}
	//cout<<RearNode->Data;
	cout<<"\n结点插入成功"<<endl;
}
template <class NodeType>
bool DoubleLinkList<NodeType>::Remove_From_Front()//头部删除 
{
	if(isEmpty())
	{
		cout<<"\n没有学生信息,无法删除!"<<endl;
		return false;
	}
	else
	{
		Node<NodeType> *CurrentNode=FirstNode;
		if(FirstNode==RearNode)
			FirstNode=RearNode=NULL;
		else
		{
			FirstNode=FirstNode->NextNode;
			FirstNode->PreviousNode=NULL;
		}
		delete CurrentNode;
		cout<<"\n成功删除第一个学生的信息"<<endl;
		return true;
		
	}
}
template <class NodeType>
bool DoubleLinkList<NodeType>::Remove_From_Rear()//尾部删除 
{
	if(isEmpty())
	{
		cout<<"没有学生信息,无法删除!"<<endl;
		return false;
	}
	else
	{
		Node<NodeType> *CurrentNode=RearNode;
		if(FirstNode==RearNode)
			FirstNode=RearNode=NULL;
		else
		{
			RearNode=RearNode->PreviousNode;
			RearNode->NextNode=NULL;
		}
		delete CurrentNode;
		cout<<"\n成功删除最后一个学生的信息"<<endl;
		return true;
	}
}
template <class NodeType>
void DoubleLinkList<NodeType>::Traverse_Forward()//头部遍历 
{
	Node<NodeType> *CurrentNode=FirstNode;
	while(CurrentNode!=NULL)
	{
		cout<<CurrentNode->Data<<" ";
		CurrentNode=CurrentNode->NextNode;
	}
}
template <class NodeType>
void DoubleLinkList<NodeType>::Tracerse_Backward()//尾部遍历 
{
	Node<NodeType> *CurrentNode=RearNode;
	while(CurrentNode!=NULL)
	{
		cout<<CurrentNode->Data<<" ";
		CurrentNode=CurrentNode->PreviousNode;
	}
	
}
template <class NodeType>
void DoubleLinkList<NodeType>::Sort_Data_By_Id()//按学号排序 
{
	Node<NodeType> *CurrentNode,*NewNode;
	NodeType TempNode;
	for(NewNode=FirstNode;NewNode!=NULL;NewNode=NewNode->NextNode)
	{
		for(CurrentNode=NewNode->NextNode;CurrentNode!=NULL;CurrentNode=CurrentNode->NextNode)
		{
			if((double)NewNode->Data>(double)CurrentNode->Data)
			{
				TempNode=CurrentNode->Data;
				CurrentNode->Data=NewNode->Data;
				NewNode->Data=TempNode;
			}
		}
	}
	cout<<"\n按学号从小到大排序成功"<<endl; 
}
template <class NodeType>
void DoubleLinkList<NodeType>::Sort_Data_By_Score()//按分数排序 
{
	Node<NodeType> *CurrentNode,*NewNode;
	NodeType TempNode;
	for(NewNode=FirstNode;NewNode!=NULL;NewNode=NewNode->NextNode)
	{
		for(CurrentNode=NewNode->NextNode;CurrentNode!=NULL;CurrentNode=CurrentNode->NextNode)
		{
			if((float)NewNode->Data<(float)CurrentNode->Data)
			{
				TempNode=CurrentNode->Data;
				CurrentNode->Data=NewNode->Data;
				NewNode->Data=TempNode;
			}
		}
	}
	cout<<"\n按分数从高到低排序成功"<<endl;
}
template <class NodeType>
void DoubleLinkList<NodeType>::Read_File()//从文件中读取信息 
{
	ifstream file("user.txt",ios::in);
	NodeType TempData;
	if(!file)
	{
		cout<<"没有原始文件!"<<endl;
		system("pause");
		exit(0);
	}
	Node<NodeType>*NewNode=new Node<NodeType>;
	NewNode->PreviousNode=NULL;
	NewNode->NextNode=NULL;
	FirstNode=RearNode=NewNode;
	file>>NewNode->Data;
	while(!file.eof())//eof()到文件末尾会读两次 
	{
		NewNode=new Node<NodeType>;
		NewNode->PreviousNode=RearNode; 
		RearNode->NextNode=NewNode;
		NewNode->NextNode=NULL;
		RearNode=NewNode;
		file>>NewNode->Data;
		//cout<<NewNode->Data<<endl;
	}
	if(RearNode==FirstNode)
	{
		delete RearNode;
		FirstNode=RearNode=NULL;
		cout<<"文件为空"<<endl; 
	}
	else
	{
		RearNode=RearNode->PreviousNode;
		delete RearNode->NextNode;
		RearNode->NextNode=NULL;
		cout<<"读取成功"<<endl;	
	}
	file.close();
}
template <class NodeType>
void DoubleLinkList<NodeType>::Write_file()//把信息写入文件中 
{
	ofstream out("user.txt");
	if(!out)
	{
		cout<<"打开文件失败!"<<endl;
		return;
	}
	Node<NodeType> *CurrentNode=FirstNode;
	while(CurrentNode!=NULL)
	{
		out<<CurrentNode->Data;
		CurrentNode=CurrentNode->NextNode;
	}
	cout<<"成功写入"<<endl;
	out.close();
}
template <class NodeType>
void DoubleLinkList<NodeType>::Search_According_Id(string p)//按学号排序 
{
	Node<NodeType> *CurrentNode=FirstNode;
	while(CurrentNode!=NULL)
	{
		if(CurrentNode->Data==p)
		{
			cout<<"该学生的信息为:"<<endl;
			cout<<CurrentNode->Data<<endl;
			return;
		}
		CurrentNode=CurrentNode->NextNode;
	}
	cout<<"没有该学生!"<<endl;
}
template <class NodeType>
void DoubleLinkList<NodeType>::Search_According_Name(string n)//按姓名查找 
{
	Node<NodeType> *CurrentNode=FirstNode;
	while(CurrentNode!=NULL)
	{
		if(CurrentNode->Data==n)
		{
			cout<<"该学生的信息为:"<<endl;
			cout<<CurrentNode->Data<<endl;
			return;
		}
		CurrentNode=CurrentNode->NextNode;
	}
	cout<<"没有改学生!"<<endl;
}
  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
一、学籍管理系统 1.问题提出 为了分析教学效果并进行相应的学籍处理,各学校每到期末都对综合成绩进行分类统计、上报成绩汇总结果等,这给每位老师和学籍管理人员带来很大工作量。使用学籍管理系统可以减少工作者的工作负担。 2.功能要求 循环显示如图7(a)所示的主菜单。 ………………………………………………….        .………………………………………………………        …………………………………………………………. 请输入选项编号(0 ~4):.        . 请输入选项编号(0 ~4):.        .请输入选项编号(0 ~4):. ………………………………………………….        .………………………………………………………        …………………………………………………………. . 1——录入成绩.                . 1——按学号排序.               . 1——生成并打印补考通知单 . . 2——统计成绩.                . 2——计算平均分并排序 .         . 2——生成并打印退学通知单 . . 3——处理学籍.                . 3——统计分数段.               . 3——生成并打印新名册. . 4——创新功能.                . 4——返回.                    . 4——返回. . 0——退出系统.                . 0——退出系统.                 . 0——退出系统. ……………………………………………………         ……………………………………………………….        …………………………………………………………. 图7(a) 学籍管理主菜单            (b)成绩统计子菜单               (c)学籍处理子菜单 在主菜单中选择1:录入成绩。假设某班的原始成绩形式如下: 学号        姓名        高数    英语    物理    编程    马哲 0909339105 Huangying  89      92      85     88     82 0909339102 Zhangchen  72      68      83     90     78 0909339108 Linan      91      84      90     79     81 …… 其中,原始数据的排列是无序的。系统应能够保留原始成绩单。 在主菜单中选择2:进入如图7(b)所示的子菜单,并统计成绩。在此可以计算平均分、统计各分数段、按学号排序、按平均分排序。在子菜单选择1时,将该班学生的成绩按学号升序排序后的顺序存入std.dat文件中,以方便打印。在子菜单选择2时,求出每位学生的平均分,并按平均分从高到低的顺序进行排序后,写入文件sort.dat中。在子菜单选择3时,统计出各门课、各分数段学生的人数,并如表1所示的形式输出。在子菜单选择4时,返回主菜单;选择0,退出整个系统。 在主菜单选择3:进入如图7(c)所示的子菜单,并处理学籍。为不及格的学生打印重考通知单时,应在通知单上写明重考的课程、时间和地点(由键盘输入)。为了参加多门课重考的学生完成补考,应避免时间重复。为3门以上不及格的学生打印退学通知单。通知单上应写明学生的学号、姓名、退学原因(几门课不及格,成绩多少)。删除已退学的学生信息,将该班中升入高年级的学生信息写入文件next.dat中。在子菜单选择4,返回主菜单;选择0,退出整个系统。 在主菜单中选择4:此项功能学生自由发挥,根据本组爱好增加与本题止相关的新功能。 在主菜单中选择0:显示结束信息(如“感谢使用本软件!已正常退出,按任意键结束。”),按任意键后,退出本功能。 表1 各门课、各分数段学生的人数 ……………………………………………………………………………………………………………….   . 90以上. 80~89分.70~79分.60~69分.60分以下. 高数.      .       .       .       .       . 英语.      .       .       .       .       . 物理.      .       .       .       .       . 编程.      .       .       .       .       . 马哲.      .       .       .       .       . ……………………………………………………………………………………………………………….

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力发光的程序员

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值