實驗六
test1
源代碼:
1 #pragma once
2 #include <iomanip>
3 #include <iostream>
4 #include <string>
5
6 struct Contestant {
7 long id; // 學號
8 std::string name; // 姓名
9 std::string major; // 專業
10 int solved; // 解題數
11 int penalty; // 總罰時
12 };
13
14 // 重載<<
15 // 要求:姓名/專業裏不含空白符
16 inline std::ostream& operator<<(std::ostream& out, const Contestant& c) {
17 out << std::left;
18 out << std::setw(15) << c.id
19 << std::setw(15) << c.name
20 << std::setw(15) << c.major
21 << std::setw(10) << c.solved
22 << std::setw(10) << c.penalty;
23
24 return out;
25 }
26
27 // 重載>>
28 inline std::istream& operator>>(std::istream& in, Contestant& c) {
29 in >> c.id >> c.name >> c.major >> c.solved >> c.penalty;
30
31 return in;
32 }
1 #include <algorithm>
2 #include <iostream>
3 #include <stdexcept>
4 #include <vector>
5 #include "contestant.hpp"
6 #include "utils.hpp"
7
8 const std::string in_file = "./data.txt";
9 const std::string out_file = "./ans.txt";
10
11 void app() {
12 std::vector<Contestant> contestants;
13
14 try {
15 contestants = load(in_file);
16 std::sort(contestants.begin(), contestants.end(), cmp_by_solve);
17 print(contestants);
18 save(out_file, contestants);
19 } catch (const std::exception& e) {
20 std::cerr << e.what() << '\n';
21 return;
22 }
23 }
24
25 int main() {
26 app();
27 }
1 #pragma once
2 #include <fstream>
3 #include <iostream>
4 #include <stdexcept>
5 #include <string>
6 #include <vector>
7 #include "contestant.hpp"
8
9 // ACM 排序規則:先按解題數降序,再按罰時升序
10 inline bool cmp_by_solve(const Contestant& a, const Contestant& b) {
11 if(a.solved != b.solved)
12 return a.solved > b.solved;
13
14 return a.penalty < b.penalty;
15 }
16
17 // 將結果寫至任意輸出流
18 inline void write(std::ostream& os, const std::vector<Contestant>& v) {
19 for (const auto& x : v)
20 os << x << '\n';
21 }
22
23 // 將結果打印到屏幕
24 inline void print(const std::vector<Contestant>& v) {
25 write(std::cout, v);
26 }
27
28 // 將結果保存到文件
29 inline void save(const std::string& filename, const std::vector<Contestant>& v) {
30 std::ofstream os(filename);
31 if (!os)
32 throw std::runtime_error("fail to open " + filename);
33
34 write(os, v);
35 }
36
37 // 從文件讀取信息(跳過標題行)
38 inline std::vector<Contestant> load(const std::string& filename) {
39 std::ifstream is(filename);
40 if (!is)
41 throw std::runtime_error("fail to open " + filename);
42
43 std::string line;
44 std::getline(is, line); // 跳過標題
45
46 std::vector<Contestant> v;
47 Contestant t;
48 int seq;
49 while (is >> seq >> t)
50 v.push_back(t);
51
52 return v;
53 }
運行結果:
問題:
1.(1)因為 std::cout 和 std::ofstream 都是 std::ostream 的派生類,基類引用可綁定派生類對象。
(2)不需要改動
2.(1)打開文件失敗時
(2)因被 app () 函數的 try-catch 捕獲,輸出錯誤信息並終止後續操作
3.可以替換,功能、結果完全一致
4
load() 函數會讀取 data_bad.txt,此時 utils.hpp 中的 load 函數未修改,導致程序提前終止
實驗二
test2
源代碼:
1 #pragma once
2
3 #include <iostream>
4 #include <string>
5
6 class Student {
7 public:
8 Student() = default;
9 ~Student() = default;
10
11 const std::string get_major() const;
12 int get_grade() const;
13
14 friend std::ostream& operator<<(std::ostream& os, const Student& s);
15 friend std::istream& operator>>(std::istream& is, Student& s);
16
17 private:
18 int id;
19 std::string name;
20 std::string major;
21 int grade; // 0-100
22 };
1 #include "student.hpp"
2
3 const std::string Student::get_major() const {
4 return major;
5 }
6
7 int Student::get_grade() const {
8 return grade;
9 }
10
11 std::ostream& operator<<(std::ostream& os, const Student& s) {
12 os << s.id << ' ' << s.name << ' ' << s.major << ' ' << s.grade;
13 return os;
14 }
15
16 std::istream& operator>>(std::istream& is, Student& s) {
17 is >> s.id >> s.name >> s.major >> s.grade;
18 return is;
19 }
1 #pragma once
2 #include <string>
3 #include <vector>
4 #include "student.hpp"
5
6 class StuMgr {
7 public:
8 void load(const std::string& file); // 加載數據文件(空格分隔)
9 void sort(); // 排序: 按專業字典序升序、同專業分數降序
10 void print() const; // 打印到屏幕
11 void save(const std::string& file) const; // 保存到文件
12
13 private:
14 void write(std::ostream &os) const; // 把數據寫到任意輸出流
15
16 private:
17 std::vector<Student> students;
18 };
1 #include "stumgr.hpp"
2 #include <fstream>
3 #include <algorithm>
4 #include <sstream>
5 void StuMgr::write(std::ostream &os) const // 把數據寫到任意輸出流
6 {
7 for (const auto& student : students) {
8 os << student << '\n';
9 }
10 }
11
12 void StuMgr::load(const std::string& file) // 加載數據文件(空格分隔)
13 {
14
15 std::ifstream is(file);
16 if (!is.is_open()) {
17 throw std::runtime_error("無法打開文件: " + file);
18 }
19
20 students.clear();
21 std::string line;
22 std::getline(is, line);
23
24 Student t;
25 int line_no = 1;
26
27 while (std::getline(is, line)) {
28 ++line_no;
29 std::istringstream ss(line);
30 if(!(ss >> t))
31 {
32 std::cerr << "[load warning] bad line " << line_no
33 << ": " << line << '\n';
34 continue;
35 }else if(t.get_grade() < 0 || t.get_grade() > 100)
36 {
37 std::cerr << "[load warning] invalid grade at line " << line_no
38 << ": " << line << '\n';
39 continue;
40 }
41 students.push_back(t);
42 }
43
44 }
45
46 void StuMgr::sort() // 排序: 按專業字典序升序、同專業分數降序
47 {
48 if (students.empty()) {
49 throw std::runtime_error("沒有加載任何學生數據,無法排序");
50 return;
51 }
52 std::sort(students.begin(), students.end(),
53 [](const Student& a, const Student& b) {
54 if (a.get_major() != b.get_major()) {
55 return a.get_major() < b.get_major();
56 }
57 return a.get_grade() > b.get_grade();
58 });
59 }
60
61 void StuMgr::print() const // 打印到屏幕
62 {
63 if (students.empty()) {
64 throw std::runtime_error("沒有加載任何學生數據,無法打印");
65 return;
66 }
67 write(std::cout);
68 }
69
70 void StuMgr::save(const std::string& file) const // 保存到文件
71 {
72 if(students.empty()) {
73 throw std::runtime_error("沒有加載任何學生數據,無法保存");
74 return;
75 }
76
77 std::ofstream out(file);
78 if(!out)
79 {
80 throw std::runtime_error("無法打開文件: " + file);
81 }
82 write(out);
83 }
1 #include <iostream>
2 #include <limits>
3 #include <string>
4 #include "stumgr.hpp"
5
6 const std::string in_file = "./data_bad.txt";
7 const std::string out_file = "./ans.txt";
8
9 void menu() {
10 std::cout << "\n**********簡易應用**********\n"
11 "1. 加載文件\n"
12 "2. 排序\n"
13 "3. 打印到屏幕\n"
14 "4. 保存到文件\n"
15 "5. 退出\n"
16 "請選擇:";
17 }
18
19 void app() {
20 StuMgr mgr;
21
22 while(true) {
23 menu();
24 int choice;
25 std::cin >> choice;
26
27 try {
28 switch (choice) {
29 case 1: mgr.load(in_file);
30 std::cout << "加載成功\n"; break;
31 case 2: mgr.sort();
32 std::cout << "排序已完成\n"; break;
33 case 3: mgr.print();
34 std::cout << "打印已完成\n"; break;
35 case 4: mgr.save(out_file);
36 std::cout << "導出成功\n"; break;
37 case 5: return;
38 default: std::cout << "不合法輸入\n";
39 }
40 }
41 catch (const std::exception& e) {
42 std::cout << "Error: " << e.what() << '\n';
43 }
44 }
45 }
46
47 int main() {
48 app();
49 }
運算結果:
本文章為轉載內容,我們尊重原作者對文章享有的著作權。如有內容錯誤或侵權問題,歡迎原作者聯繫我們進行內容更正或刪除文章。