实验6 模板类、文件I/O和异常处理
实验任务4
代码
Vector.hpp
1 #pragma once 2 #include <iostream> 3 #include <stdexcept> 4 5 template <typename T> 6 class Vector { 7 public: 8 // 构造函数 9 Vector(int size); 10 Vector(int size, T value); 11 Vector(const Vector<T>& other); // 拷贝构造函数 12 ~Vector(); // 析构函数 13 14 // 成员函数 15 int get_size() const; // 返回数组大小 16 T& at(int index); // 访问元素,带边界检查 17 const T& at(int index) const; // 访问元素(常量版本) 18 19 // 重载运算符[] 20 T& operator[](int index); 21 const T& operator[](int index) const; 22 23 // 友元函数 24 template <typename U> 25 friend void output(const Vector<U>& v); 26 27 private: 28 int size; // 数组大小 29 T* data; // 动态数组指针 30 }; 31 32 // 构造函数:创建指定大小的数组 33 template <typename T> 34 Vector<T>::Vector(int size) : size(size) { 35 if (size < 0) throw std::length_error("Vector constructor: negative size"); 36 data = new T[size]{}; // 初始化数组 37 } 38 39 // 构造函数:创建指定大小并初始化为value的数组 40 template <typename T> 41 Vector<T>::Vector(int size, T value) : size(size) { 42 if (size < 0) throw std::length_error("Vector constructor: negative size"); 43 data = new T[size]; 44 for (int i = 0; i < size; ++i) data[i] = value; 45 } 46 47 // 拷贝构造函数:实现深拷贝 48 template <typename T> 49 Vector<T>::Vector(const Vector<T>& other) : size(other.size) { 50 data = new T[size]; 51 for (int i = 0; i < size; ++i) data[i] = other.data[i]; 52 } 53 54 // 析构函数:释放动态分配的内存 55 template <typename T> 56 Vector<T>::~Vector() { 57 delete[] data; 58 } 59 60 // 获取数组大小 61 template <typename T> 62 int Vector<T>::get_size() const { 63 return size; 64 } 65 66 // 访问元素,带边界检查 67 template <typename T> 68 T& Vector<T>::at(int index) { 69 if (index < 0 || index >= size) throw std::out_of_range("Vector: index out of range"); 70 return data[index]; 71 } 72 73 // 访问元素(常量版本) 74 template <typename T> 75 const T& Vector<T>::at(int index) const { 76 if (index < 0 || index >= size) throw std::out_of_range("Vector: index out of range"); 77 return data[index]; 78 } 79 80 // 重载运算符[] 81 template <typename T> 82 T& Vector<T>::operator[](int index) { 83 return at(index); 84 } 85 86 template <typename T> 87 const T& Vector<T>::operator[](int index) const { 88 return at(index); 89 } 90 91 // 友元函数:输出Vector对象 92 template <typename U> 93 void output(const Vector<U>& v) { 94 for (int i = 0; i < v.size; ++i) { 95 std::cout << v.data[i] << " "; 96 } 97 std::cout << std::endl; 98 }
task4.cpp
1 #include <iostream> 2 #include "Vector.hpp" 3 4 using namespace std; 5 6 void test1() { 7 int n; 8 cout << "Enter n: "; 9 cin >> n; 10 11 Vector<double> x1(n); 12 for(auto i = 0; i < n; ++i) 13 x1.at(i) = i * 0.7; 14 15 cout << "x1: "; output(x1); 16 17 Vector<int> x2(n, 42); 18 const Vector<int> x3(x2); 19 20 cout << "x2: "; output(x2); 21 cout << "x3: "; output(x3); 22 23 x2.at(0) = 77; 24 x2.at(1) = 777; 25 cout << "x2: "; output(x2); 26 cout << "x3: "; output(x3); 27 } 28 29 void test2() { 30 using namespace std; 31 32 int n, index; 33 while(cout << "Enter n and index: ", cin >> n >> index) { 34 try { 35 Vector<int> v(n, n); 36 v.at(index) = -999; 37 cout << "v: "; output(v); 38 } 39 catch (const exception &e) { 40 cout << e.what() << endl; 41 } 42 } 43 } 44 45 int main() { 46 cout << "测试1: 模板类接口测试\n"; 47 test1(); 48 49 cout << "\n测试2: 模板类异常处理测试\n"; 50 test2(); 51 }
运行结果
实验任务5
代码
task5.cpp
1 #include <iostream> 2 #include <fstream> 3 #include <string> 4 #include <vector> 5 #include <algorithm> 6 #include <iomanip> 7 8 using namespace std; 9 10 // 学生成绩类 11 class Student { 12 public: 13 int id; // 学号 14 string name; // 姓名 15 string major; // 专业 16 double score; // 分数 17 18 // 重载输入运算符,读取学号、姓名、专业、分数 19 friend istream& operator>>(istream& in, Student& s); 20 // 重载输出运算符,格式化输出学号、姓名、专业、分数 21 friend ostream& operator<<(ostream& out, const Student& s); 22 }; 23 24 // 输入运算符重载 25 istream& operator>>(istream& in, Student& s) { 26 in >> s.id >> s.name >> s.major >> s.score; 27 return in; 28 } 29 30 // 输出运算符重载 31 ostream& operator<<(ostream& out, const Student& s) { 32 out << left << setw(10) << s.id 33 << setw(10) << s.name 34 << setw(10) << s.major 35 << fixed << setprecision(2) << s.score; 36 return out; 37 } 38 39 int main() { 40 vector<Student> students; 41 42 // 输入和输出文件路径 43 const string input_file = "C:\\Users\\陈昕\\Desktop\\实验6文档部分代码和数据文件\\task5\\data5.txt"; 44 const string output_file = "C:\\Users\\陈昕\\Desktop\\实验6文档部分代码和数据文件\\task5\\ans5.txt"; 45 46 ifstream infile(input_file); 47 ofstream outfile(output_file); 48 49 // 检查输入文件是否打开成功 50 if (!infile.is_open()) { 51 cerr << "Error: Unable to open input file at " << input_file << endl; 52 return 1; 53 } 54 55 cout << "Reading data from " << input_file << "..." << endl; 56 57 // 跳过文件的第一行(表头) 58 string header; 59 getline(infile, header); // 读取并丢弃表头 60 61 // 读取数据到 vector 62 Student temp; 63 while (infile >> temp) { 64 students.push_back(temp); 65 } 66 infile.close(); 67 68 // 检查是否读取到数据 69 if (students.empty()) { 70 cerr << "Error: No data found in file " << input_file << endl; 71 return 1; 72 } 73 74 // 排序规则:按专业字典序排序,同专业内按分数降序排序 75 sort(students.begin(), students.end(), [](const Student& a, const Student& b) { 76 if (a.major == b.major) return a.score > b.score; // 分数降序 77 return a.major < b.major; // 专业字典序 78 }); 79 80 // 输出标题行 81 cout << left << setw(10) << "ID" 82 << setw(10) << "Name" 83 << setw(10) << "Major" 84 << "Score" << endl; 85 86 // 输出到屏幕 87 for (const auto& s : students) { 88 cout << s << endl; 89 } 90 91 // 输出到文件 92 if (outfile.is_open()) { 93 outfile << left << setw(10) << "ID" 94 << setw(10) << "Name" 95 << setw(10) << "Major" 96 << "Score" << endl; 97 98 for (const auto& s : students) { 99 outfile << s << endl; 100 } 101 outfile.close(); 102 cout << "Sorted results have been written to " << output_file << endl; 103 } else { 104 cerr << "Error: Unable to open output file at " << output_file << endl; 105 return 1; 106 } 107 108 return 0; 109 }
运行结果