实验6 模板类,文件I/O和异常处理
一、实验目的
练习编写模板函数,模板类,从多态角度理解模板函数和模板类(类型作为参数)
体验标准I/O流类,文件I/O流类,字符串I/O流类的用法,能正确使用
针对问题场景,使用流类库对I/O数据进行格式化和读写操作
体验异常处理的基础用法,能解释异常处理的机制和流程
训练综合应用类的封装,继承,多态特性及现代C++标准库编写正确,高效,安全代码
二、实验准备
函数模板和函数类
流类库与输入输出
异常处理
三、实验内容
4. 实验任务4
代码:
头文件
1 #pragma once 2 #include<iostream> 3 #include<stdexcept> 4 using namespace std; 5 template <typename T> 6 class Vector { 7 public: 8 9 //构造函数 10 //支持在创建抽象数据类型T类型数组对象时,动态指定其大小 11 Vector(int size) :size{ size } { 12 if (size < 0) 13 throw length_error("negative size");//异常抛出 14 15 16 else 17 { 18 ptr = new T[size];//申请内存 19 20 } 21 22 } 23 //构造函数 24 //支持在创建T类型数组对象时,指定其大小,并将数组对象中每个数据项初始化到T类型的值value 25 26 27 Vector(int s, T value) :size(s) { 28 if (s < 0) 29 throw length_error("negative size");//异常抛出 30 else 31 { 32 ptr = new T[size]; 33 for (int i = 0; i < s; i++) 34 *(ptr + i) = value; 35 } 36 } 37 38 //支持用已经存在的 Vector<T> 数组对象x,来构造新的对象y(要求实现深复制) 39 Vector(const Vector<T>& x) :size(x.size), ptr(new T[size]) { 40 for (int i = 0; i < size; i++) { 41 ptr[i] = x.ptr[i]; 42 } 43 } 44 45 //析构函数 46 ~Vector() { delete[]ptr; } 47 48 //接口 49 50 51 //1 52 int get_size()const { 53 return size; 54 } 55 56 //2 57 T& at(int val) { 58 if (val >= size)throw out_of_range("index out of range"); 59 else return ptr[val]; 60 61 } 62 63 //3重载[] 64 T& operator[](int val) { 65 if (val < 0 || val >= size)throw out_of_range("index out of range"); 66 else return ptr[val]; 67 } 68 69 //友元函数 70 71 //output() 72 friend void output(const Vector<T>& x) { 73 for (int i = 0; i < x.get_size(); i++) { 74 cout << x.ptr[i] << ", ";//遍历输出 75 } 76 cout << endl; 77 78 } 79 80 81 82 private: 83 int size; 84 T* ptr; 85 };
测试代码:
1 #include <iostream> 2 #include "Vector.hpp" 3 using namespace std; 4 5 void test1() { 6 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. 实验任务5
代码:
1 #include <iostream> 2 #include <fstream> 3 #include <sstream> 4 #include <vector> 5 #include <algorithm> 6 #include <string> 7 8 // 自定义学生结构体 9 struct Student { 10 int id; // 学号 11 std::string name; // 姓名 12 std::string major; // 专业 13 int score; // 成绩 14 }; 15 16 // 重载小于运算符,以便根据专业和成绩排序 17 bool operator<(const Student& a, const Student& b) { 18 return (a.major == b.major) ? (a.score > b.score) : (a.major < b.major); 19 } 20 21 // 从文件读取学生信息 22 std::vector<Student> readStudentsFromFile(const std::string& filename) { 23 std::vector<Student> students; 24 std::ifstream file(filename); 25 std::string line; 26 27 // 跳过第一行 28 std::getline(file, line); 29 30 // 逐行读取学生信息 31 while (std::getline(file, line)) { 32 std::istringstream iss(line); 33 Student student; 34 iss >> student.id >> student.name >> student.major >> student.score; 35 students.push_back(student); 36 } 37 38 return students; 39 } 40 41 // 将学生信息写入文件 42 void writeStudentsToFile(const std::vector<Student>& students, const std::string& filename) { 43 std::ofstream file(filename); 44 for (const auto& student : students) { 45 file << student.id << "\t" << student.name << "\t" << student.major << "\t" << student.score << '\n'; 46 } 47 } 48 49 // 主函数 50 int main() { 51 // 读取学生信息 52 auto students = readStudentsFromFile("data5.txt"); 53 54 // 按照自定义规则排序 55 std::sort(students.begin(), students.end()); 56 57 // 输出排序后的学生信息 58 std::cout << "学号\t姓名\t专业\t分数" << std::endl; 59 for (const auto& student : students) { 60 std::cout << student.id << "\t" << student.name << "\t" << student.major << "\t" << student.score << std::endl; 61 } 62 63 // 写入结果到文件 64 writeStudentsToFile(students, "ans5.txt"); 65 return 0; 66 }
运行截图: