实验6
实验1
#pragma once #include<iomanip> #include<iostream> #include<string> struct Contestant{ long id; std::string name; std::string major; int solved; int penalty; }; inline std::ostream& operator<<(std::ostream& out,const Contestant& c){ out << std::left; out << std::setw(15) << c.id << std::setw(15) << c.name << std::setw(15) << c.major << std::setw(15) << c.solved << std::setw(15) << c.penalty; return out; } inline std::istream& operator>>(std::istream& in,Contestant& c){ in >> c.id >> c.name >> c.major >> c.solved >> c.penalty; return in; }
#pragma once #include<fstream> #include<iostream> #include<stdexcept> #include<string> #include<vector> #include "contestant.hpp" inline bool cmp_by_solve(const Contestant& a,const Contestant& b){ if(a.solved!=b.solved) return a.solved>b.solved; return a.penalty<b.penalty; } inline void write(std::ostream& os,const std::vector<Contestant>& v){ for(const auto& x:v) os << x << '\n'; } inline void print(const std::vector<Contestant>& v){ write(std::cout,v); } inline void save(const std::string& filename,const std::vector<Contestant>& v){ std::ofstream os(filename); if(!os) throw std::runtime_error("fail to open " + filename); write(os,v); } inline std::vector<Contestant> load(const std::string& filename){ std::ifstream is(filename); if(!is) throw std::runtime_error("fail to open " + filename); std::string line; std::getline(is,line); std::vector<Contestant> v; Contestant t; int seq; while(is >> seq >> t) v.push_back(t); return v; }
#include<algorithm> #include<iostream> #include<stdexcept> #include<vector> #include "contestant.hpp" #include "utils.hpp" const std::string in_file="./data.txt"; const std::string out_file="./ans.txt"; void app(){ std::vector<Contestant> contestants; try{ contestants=load(in_file); std::sort(contestants.begin(),contestants.end(),cmp_by_solve); print(contestants); save(out_file,contestants); }catch(const std::exception& e){ std::cerr << e.what() << '\n'; return; } } int main(){ app(); }


问题1:
(1)std::ostream是所有输出流的基类,std::cout和std::ofstream都继承自std::ostream。基类引用可以接受所有派生类对象。
(2)不需要,write()函数接收std::ostream&参数,可以接受任何继承自std::ostream类的对象。
问题2:
if(!os)
throw std::runtime_error("fail to open " + filename);
if(!is)
throw std::runtime_error("fail to open " + filename);
(1)save()函数:当无法打开指定文件进行写入时会抛出异常;load()函数:当无法打开指定文件进行读取时会抛出异常。
(2)异常被app()中catch(conat std::exception& e)捕获,会将异常信息输出,然后返回,程序终止。
问题3:
可以,功能、性能、结果一致。
问题4:

数据部分缺失,当前 load() 函数使用了简单循环:一旦出现空白行或者数据类型不匹配之类的就会导致is >> t 失败,流入 fail 状态,后续读取全部被跳过。
实验2
#pragma once #include<iostream> #include<string> class Student{ public: Student()=default; ~Student()=default; const std::string get_major() const; int get_grade() const; friend std::ostream& operator<<(std::ostream& os,const Student& s); friend std::istream& operator>>(std::istream& is,Student& s); private: int id; std::string name; std::string major; int grade; };
#include<iostream> #include<string> #include<iomanip> #include "student.hpp" const std::string Student::get_major() const{ return major; } int Student::get_grade() const{ return grade; } std::ostream& operator<<(std::ostream& os,const Student& s){ os << std::left; os << std::setw(15) << s.id << std::setw(15) << s.name << std::setw(15) << s.major << std::setw(15) << s.grade; return os; } std::istream& operator>>(std::istream& is,Student& s){ is >> s.id >> s.name >> s.major >> s.grade; return is; }
#pragma once #include<string> #include<vector> #include "student.hpp" class StuMgr{ public: void load(const std::string& file); void sort(); void print() const; void save(const std::string& file) const; private: void write(std::ostream &os) const; private: std::vector<Student> students; };
#include<iostream> #include<fstream> #include<algorithm> #include<stdexcept> #include<string> #include<vector> #include "stumgr.hpp" bool func(const Student& a,const Student& b){ if(a.get_major()!=b.get_major()) return a.get_major()<b.get_major(); return a.get_grade()>b.get_grade(); } void StuMgr::load(const std::string& file){ std::ifstream is(file); if(!is) throw std::runtime_error("fail to open " + file); std::string line; std::getline(is,line); Student t; while(is >> t){ students.push_back(t); } } void StuMgr::sort(){ std::sort(students.begin(),students.end(),func); } void StuMgr::print() const{ if(students.empty()){ std::cout << "没有学生数据\n"; return; } write(std::cout); } void StuMgr::save(const std::string& file) const{ std::ofstream os(file); if(!os) throw std::runtime_error("fail to open " + file); write(os); } void StuMgr::write(std::ostream &os) const{ for(const auto& s:students) os << s << '\n'; }
#include<iostream> #include<limits> #include<string> #include "stumgr.hpp" const std::string in_file="./data.txt"; const std::string out_file="./ans.txt"; void menu(){ std::cout << "\n**********简易应用**********\n" << "1.加载文件\n" << "2.排序\n" << "3.打印到屏幕\n" << "4.保存到文件\n" << "5.退出\n" << "请选择:"; } void app(){ StuMgr mgr; while(true){ menu(); int choice; std::cin >> choice; try{ switch(choice){ case 1:mgr.load(in_file); std::cout << "加载成功\n";break; case 2:mgr.sort(); std::cout << "排序已完成\n";break; case 3:mgr.print(); std::cout << "打印已完成\n";break; case 4:mgr.save(out_file); std::cout << "导出成功\n";break; case 5:return; default:std::cout << "不合法输入\n"; } } catch(const std::exception& e){ std::cout << "Error:" << e.what() << '\n'; } } } int main(){ app(); }




浙公网安备 33010602011771号