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