Algorithm: 学生成绩管理系统

 

C++学生成绩管理系统
编写一个统计存储在文件中的学生成绩管理程序。设学生成绩以一个学生一条记录的形式存储在文件中。每一个学生记录的信息有姓名﹑学号和各门功课的成绩。
功能以下:
1. 求各门课程的总分﹑平均分。
2.按姓名寻找记录并显示。
3.  按学号寻找记录并显示。
4.查询所有学生成绩。
5.按总分由高到低显示学生信息。        
提示:设每位学生语文﹑数学﹑英语3门课程。主程序输入文件名后,进入接受命令﹑执行命令处理程序循环。
按问题的要求共设5条命令:
 1. 求各门课程的总分。
2.求各门课程的平均分。
 3.按姓名寻找记录并显示。
 4.  按学号寻找记录并显示。
 5.结束命令
为求各门课程的总分,从文件中逐一读出学生记录。累计各门课程的分数,待文件处理完便可获得各门课程的总分。为求各门课程的平均分,从文件中逐一读出学生记录。累计各门课程的分数。并统计学生人数,待文件处理完毕,将获得的各门课程的平均分。按学生名字寻找学生信息的处理,首先要求输入待寻找学生的名字,顺序读入学生记录。凡名字与待寻找学生的名字相同的记录在屏幕上显示,直到文件结束。按学生学号寻找学生信息的处理,首先要求输入待寻找学生的学号,顺序读入学生记录。凡学号与待寻找学生的学号相同的记录在屏幕上显示,直到文件结束。浏览学生所有成绩,顺序读入学生记录。并在屏幕上显示,直到文件结束。按总分由高到低显示学生信息。顺序读入学生记录并构造一个有序链表。而后显示链表上的元素ios

 

/* minGW 4.8.1及以上版本编译器下编译 */
#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>
#include <string>
#include <type_traits>
#include <array>

enum Subject : int{
	Chinese = 0,
	Math = 1,
	English = 2
};

template<typename T>
typename std::remove_reference<T>::type&& my_move(T&& value)noexcept
{
	using type = typename std::remove_reference<T>::type&&;
	return static_cast<type>(value);
}


class StudentInfo{
	private:
		std::string name_;
		std::string id_;
		int chinese_; 
		int math_;
		int english_;
		
		inline int& getChineseScore()noexcept
		{
			return (this->chinese_);
		}
		
		inline int getChineseScore()const noexcept
		{
			return (this->chinese_);
		}
		
		inline int& getMathScore()noexcept
		{
			return (this->math_);
		}
		
		inline int getMathScore()const noexcept
		{
			return (this->math_);
		}
		
		inline int& getEnglishScore()noexcept
		{
			return (this->english_);
		}
		
		inline int getEnglishScore()const noexcept
		{
			return (this->english_);
		}
		
		using array = int& (StudentInfo::*)()noexcept;
		using cArray = int (StudentInfo::*)()const noexcept;
		
		array functionArray[3] = {&StudentInfo::getChineseScore, &StudentInfo::getMathScore, &StudentInfo::getEnglishScore};
		
		cArray functionCArray[3] = {static_cast<cArray>(&StudentInfo::getChineseScore), static_cast<cArray>(&StudentInfo::getMathScore), 
		                            static_cast<cArray>(&StudentInfo::getEnglishScore)};
		
		public:
			
			StudentInfo()=default;
			StudentInfo(const std::string& name, const std::string& id, const int& chinese=0, const int& math=0, const int& english=0);
			~StudentInfo()=default;
			
			StudentInfo(const StudentInfo& other);
			StudentInfo(StudentInfo&& other);
			StudentInfo& operator=(const StudentInfo& other);
			StudentInfo& operator=(StudentInfo&& other);
			int& getScore(const Subject& obj)noexcept;
			int  getScore(const Subject& obj)const noexcept;
			
			inline std::string& getId()noexcept
			{
				return (this->id_);
			}
			
			inline std::string getId()const noexcept
			{
				return (this->id_);
			}
			
			friend bool operator==(const StudentInfo& lh, const StudentInfo& rh)noexcept;
			friend std::ostream& operator<<(std::ostream& os, const StudentInfo& student);
			
};

StudentInfo::StudentInfo(const std::string& name, const std::string& id, const int& chinese, const int& math, const int& english)
            :name_(name),
             id_(id),
             chinese_(chinese),
             math_(math),
             english_(english)
{
	//constructor.
}

StudentInfo::StudentInfo(const StudentInfo& other)
            :name_(other.name_),
             id_(other.id_),
             chinese_(other.chinese_),
             math_(other.math_),
             english_(other.english_)
{
	//copy-constructor.
}

StudentInfo::StudentInfo(StudentInfo&& other)
            :name_(my_move(other.name_)),
             id_(my_move(other.id_)),
             chinese_(my_move(other.chinese_)),
             math_(my_move(other.math_)),
             english_(my_move(other.english_))
{
	//move-constructor.
}

StudentInfo& StudentInfo::operator=(const StudentInfo& other)
{

		this->name_ = other.name_;
		this->id_ = other.id_;
		this->chinese_ = other.chinese_;
		this->math_ = other.math_;
		this->english_ = other.english_;
	
	return *this;
}

StudentInfo& StudentInfo::operator=(StudentInfo&& other)
{
	this->name_ = my_move(other.name_);
	this->id_ = my_move(other.id_),
	this->chinese_ = my_move(other.chinese_);
	this->math_ = my_move(other.math_),
	this->english_ = my_move(other.english_);
	
	return *this;
}

std::ostream& operator<<(std::ostream& os, const StudentInfo& student)
{
	os<< student.name_ << " " << student.id_ << " " << student.chinese_ << " "
	  << student.math_ << " " << student.english_;
	  
	  return os;
}

int& StudentInfo::getScore(const Subject& obj)noexcept
{
	return (this->*functionArray[static_cast<int>(obj)])(); //注意这里->*,由于是成员函数的指针. 
}


int StudentInfo::getScore(const Subject& obj)const noexcept
{
	int index = static_cast<int>(obj);
	return (this->*functionCArray[index])();
}

bool operator==(const StudentInfo& lh, const StudentInfo& rh)noexcept
{
	if(lh.id_ == rh.id_){
		return true;
	}
	
	return false;
}

class RWFile{
	private:
		
		class FindObject{
			private:
				std::pair<std::string, std::string> getNameAndId(const std::string& sTr)noexcept //得到名字. 
				{
					std::pair<std::string, std::string> nameAndID;
					
					std::string name;
					std::string ID;
					std::size_t indexS;
					std::size_t indexE;
					
					if(!sTr.empty()){
						std::runtime_error(std::string("Cant not get data!"));
					}
					
					indexS = sTr.find(std::string("姓名"));
					indexE = sTr.find_first_of(" ");
					
					name = sTr.substr(indexS, indexE);
					indexS = name.find_first_of(":");
					name = name.substr(indexS + 1);
					
					nameAndID.first = name; //得到名字.
					
					indexS = sTr.find(std::string("学号"));
					name = sTr.substr(indexS);
					indexS = name.find_first_of(":");
					indexE =  name.find_first_of(" ");
					ID = name.substr(indexS+1, indexE);
					indexE = ID.find_first_of(" ");
					ID = ID.substr(0, indexE);
					
					nameAndID.second = ID;  //保存得到的ID. 
					
					return nameAndID;
				}
				
				std::array<int, 3> getScore(const std::string& sTr)noexcept
				{
					std::array<int, 3> scores; //保存各个学科的成绩.
					std::string scoreStr;
					std::size_t indexS;
					std::size_t indexE;
					
					if(!sTr.empty()){
						std::runtime_error(std::string("Can not read data!"));
						
					} 
					
					indexS = sTr.find_first_of(std::string("语文"));
					scoreStr = sTr.substr(indexS);
					indexS = scoreStr.find_first_of(":");
					indexE = scoreStr.find_first_of(" ");
					scoreStr = scoreStr.substr(indexS+1, indexE);
					indexE = scoreStr.find_first_of(" ");
					scoreStr = scoreStr.substr(0, indexE);
					
					scores[0] = std::stod(scoreStr);  //存储语文成绩.
					
					indexS = sTr.find_first_of(std::string("数学"));
					scoreStr = sTr.substr(indexS);
					indexS = scoreStr.find_first_of(":");
					indexE = scoreStr.find_first_of(" ");
					scoreStr = scoreStr.substr(indexS+1, indexE);
					indexE = scoreStr.find_first_of(" ");
					scoreStr = scoreStr.substr(0, indexE);
					
					scores[1] = std::stod(scoreStr);  //存储数学成绩.
					
					indexS = sTr.find_last_of(":");
					scoreStr = sTr.substr(indexS+1);
					
					scores[2] = std::stod(scoreStr);  //存储英语成绩. 
					
				}
				
			public:
				FindObject()=default;
				~FindObject()=default;
				
				StudentInfo operator()(const std::string& sTr)  //构建学生信息. 
				{
					std::pair<std::string, std::string> pair = this->getNameAndId(sTr);
					std::array<int, 3> array = this->getScore(sTr);
					
					StudentInfo student(pair.first, pair.second, array[0], array[1], array[2]);
					
					return student;
				}
		};
		
		std::vector<StudentInfo> students_{};
		std::string file_name_;
		std::ifstream read_txt_;    //读取txt文件里的内容读取完毕后txt文件为空.
		std::ofstream write_txt_;   //写入内容到txt文件中. 
		std::fstream stream_;       //读取文件中的内容可是不会修改原来txt中的内容. 
		
		//std::pair<object, std::vector<double>> average_{};          //该学科的全部同窗的成绩. 
		//std::pair<name, std::vector<StudentInfo>> name_search_{};  //姓名索引.
		//std::pair<id, StudentInfo> id_search{};                   //id索引
		
		void readContents();
		void closeDoc()noexcept;
		void saveContentToDoc()noexcept;
		 
		
		public:
			using ID = std::string;
			using name = std::string;
			using object = std::string;
			
			RWFile();
			RWFile(const std::string& txt);
			~RWFile()=default;
			RWFile(const RWFile& other) = delete;
			RWFile& operator=(const RWFile& other) = delete;
			
			void searchObjectAverage(const Object& obj);
			//void searchID(const std::string& idStr);
			//void searchName(const std::string& nameStr);
			void showAllBody()const noexcept;
			void changeScore(const double& realScore, const std::string& id, const Object& obj);
};

RWFile::RWFile()
       :file_name_(std::string(""))
{
	std::cout<< "Please enter the name of t(e)xt:  "<<std::endl;
	std::cin>> (this->file_name_);
	
	(this->stream_).open(this->file_name_);
	if(!(this->stream_).is_open()){
		std::cout<< "There is not this text: "<< (this->file_name_)<< ".  Plese enter again"<<std::endl;
		std::cin>>(this->file_name_);
		(this->stream_).open(this->file_name_);
		(this->stream_).close();
	}
	
	this->readContents();
}

RWFile::RWFile(const std::string& txt)try
       :file_name_(txt)
{
	(this->stream_).open(this->file_name_);
	if(!(this->stream_).is_open()){
		throw std::runtime_error(std::string("Please give a conrrect name!"));
	}
	(this->stream_).close();
	
	this->readContents();
	
}catch(const std::runtime_error& error){
	std::cout<< error.what() <<std::endl;
}

void RWFile::readContents()
{
	FindObject find;
	std::string str;
	
	(this->read_txt_).open(this->file_name_, std::fstream::out);
	while(getline((this->read_txt_), str)){   //读取txt文件. 
		
		StudentInfo student = find(str);
		(this->students_).push_back(student);
	}
	
	(this->students_).shrink_to_fit();
	(this->read_txt_).close();
}

void RWFile::searchObjectAverage(const Subject& obj)
{
	int totalScore;
	
	if(!(this->students_).empty()){
		for(const StudentInfo& student : (this->students_)){
			
			totalScore += (student.getScore(obj));
			
		}
	}
	 
	std::cout<< "This object total score: " << totalScore <<std::endl;
	std::cout<< "The average of this object: " << totalScore/(this->students_).size() <<std::endl;
}

void RWFile::changeScore(const double& realScore, const std::string& id, const Object& obj)
{
	if(!(this->students_).empty()){
		
		for(StudentInfo& student : (this->students_)){
			if(id == student.getId()){
				student.getScore(obj) = realScore;
			}
		}
	}
	
	this->saveContentToDoc();
}

void RWFile::closeDoc()noexcept
{
	if(!(this->stream_).is_open()){
		(this->stream_).close();
	}
	
	if(!(this->read_txt_).is_open()){
		(this->read_txt_).close();
	}
	
	if(!(this->write_txt_).is_open()){
		(this->write_txt_).close();
	}
}

void RWFile::saveContentToDoc()noexcept
{
	(this->write_txt_).open(this->file_name_, std::ofstream::in);
	
	if((this->write_txt_).is_open() && !(this->students_).empty()){
		for(const StudentInfo& info : (this->students_)){
			(this->write_txt_) << info << '\n';
		}
	}
	
}

void RWFile::showAllBody()const noexcept
{
	if(!(this->students_).empty()){
		for(const StudentInfo student : (this->students_)){
			std::cout<< student <<std::endl;
		}
	}
}

int main()
{
	std::string ID("013");
	std::string Dir("成绩.txt");
	RWFile system(Dir);
	
	system.showAllBody();
	system.searchObjectAverage(Object::Math);
	system.changeScore(150, ID, Object::Math);
	
	return 0;
}
相关文章
相关标签/搜索