实验6

#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(10) << c.solved
        << std::setw(10) << 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"
// ACM 排序规则:先按解题数降序,再按罚时升序
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 = "D:/test/1/data.txt";
const std::string out_file = "D:/test/1/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.1std::cout 继承自 std::ostream ,是它的的派生类对象

基类引用可以接收派生类对象

1.2不需要

2.1if (!is) / if (!os)打开输入,输出文件失败时;

2.2 try-catch,catch (const std::exception& e)

3.1可以,一致

4.1

image

 有错误数据,输出错误

 

image

 

image

 

#include "stumgr.hpp"
#include "student.hpp"
#include <fstream>
#include <stdexcept>
#include <algorithm>

// 加载文件(读取data.txt,跳过标题行)
void StuMgr::load(const std::string& file) {
    std::ifstream is(file);
    if (!is.is_open()) {
        throw std::runtime_error("cannot open file: " + file);
    }

    // 清空原有数据
    students.clear();

    // 跳过标题行
    std::string title;
    std::getline(is, title);

    // 读取学生数据
    Student s;
    while (is >> s) {
        students.push_back(s);
    }

    // 检查是否读取到数据
    if (students.empty()) {
        throw std::runtime_error("文件无有效数据");
    }
}

// 排序:专业字典序升序 → 同专业成绩降序
void StuMgr::sort() {
    std::sort(students.begin(), students.end(),
        [](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();
        });
}

// 打印到屏幕(调用write输出到std::cout)
void StuMgr::print() const {
    write(std::cout);
}

// 保存到文件(调用write输出到文件流)
void StuMgr::save(const std::string& file) const {
    std::ofstream os(file);
    if (!os.is_open()) {
        throw std::runtime_error("cannot open file: " + file);
    }
    write(os);
}

// 通用写操作:将数据写入任意输出流(复用代码)
void StuMgr::write(std::ostream& os) const {
    for (const auto& s : students) {
        os << s << '\n';
    }
}
#include "student.hpp"
#include <iomanip>
#include <stdexcept>

// 获取专业(供排序用)
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(6) << s.id
        << std::setw(8) << s.name
        << std::setw(8) << s.major
        << std::setw(4) << s.grade;
    return os;
}

// 重载输入流:读取学生信息(并校验成绩合法性)
std::istream& operator>>(std::istream& is, Student& s) {
    is >> s.id >> s.name >> s.major >> s.grade;
    // 校验成绩是否在0-100之间
    if (s.grade < 0 || s.grade > 100) {
        throw std::invalid_argument("成绩必须在0-100之间");
    }
    return is;
}

image

 

posted @ 2025-12-23 23:26  HdYi  阅读(5)  评论(0)    收藏  举报