实验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();
}

image

 

image

 

问题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:

image

 数据部分缺失,当前 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();
}

image

 

image

 

image

 

posted @ 2025-12-23 19:57  wifi战斗机  阅读(4)  评论(0)    收藏  举报