首页 > 其他分享 >实验6 模板类、文件I/O和异常处理

实验6 模板类、文件I/O和异常处理

时间:2024-12-21 20:10:46浏览次数:10  
标签:std 文件 const get Complex 实验 return include 模板

任务一:

Complex.hpp

#pragma once

#include <iostream>
#include <stdexcept>

// 声明
////////////////////////////////////////////////////
// 复数模板类声明
template<typename T>
class Complex {
public:
    Complex(T r = 0, T i = 0);
    Complex(const Complex<T> &c);

    T get_real() const;
    T get_imag() const;

    // 重载+=为成员函数
    Complex<T>& operator+=(const Complex<T> &c);

    // 重载<<、>>为友元函数
    template<typename T1>
    friend std::ostream& operator<<(std::ostream &out, const Complex<T1> &c);

    template<typename T1>
    friend std::istream& operator>>(std::istream &in, Complex<T1> &c);

private:
    T real, imag;
};

// 普通函数声明
// 重载+用于Complex类型
template<typename T>
Complex<T> operator+(const Complex<T> &c1, const Complex<T> &c2);

// 重载==用于Complex类型
template<typename T>
bool operator==(const Complex<T> &c1, const Complex<T> &c2);


// 实现
////////////////////////////////////////////////////
// 成员函数模板实现
template<typename T>
Complex<T>::Complex(T r, T i): real{r}, imag{i} {
}

template<typename T>
Complex<T>::Complex(const Complex<T> &c): real{c.real}, imag{c.imag} {
}

template<typename T>
T Complex<T>::get_real() const {
    return real;
}

template<typename T>
T Complex<T>::get_imag() const {
    return imag;
}

// 重载+=为成员函数
template<typename T>
Complex<T>& Complex<T>::operator+=(const Complex<T> &c) {
    real += c.real;
    imag += c.imag;

    return *this;
}

///////////////////////////////////////
// 友元函数模板实现
template<typename T1>
std::ostream& operator<<(std::ostream &out, const Complex<T1> &c) {
    if(c.imag >= 0)
        out << c.real << " + " << c.imag << "i";
    else
        out << c.real << " - " << -c.imag << "i";
    
    return out;
}

template<typename T1>
std::istream& operator>>(std::istream &in, Complex<T1> &c) {
    in >> c.real >> c.imag;

    return in;
}

///////////////////////////////////////
// 普通函数模板实现
// 重载+用于Complex类型
template<typename T>
Complex<T> operator+(const Complex<T> &c1, const Complex<T> &c2) {
    return Complex<T>(c1.get_real()+c2.get_real(), 
                      c1.get_imag()+c2.get_imag());
}

// 重载==用于Complex类型
template<typename T>
bool operator==(const Complex<T> &c1, const Complex<T> &c2) {
    return c1.get_real() == c2.get_real() && 
           c1.get_imag() && c2.get_imag();
}

task1.cpp

#include "Complex.hpp"
#include <iostream>
#include <fstream>
#include <stdexcept>

void test1();
void test2();

int main() {
    using namespace std;

    cout << "测试1: 复数模板类测试" << endl;
    test1();

    cout << "\n测试2: 文件I/O测试" << endl;
    test2();
}

void test1() {
    using namespace std;

    Complex<double> c1{3.5, 2}, c2;
    cout << "Enter c2: ";
    cin >> c2;
    cout << "c1 = " << c1 << endl;
    cout << "c2 = " << c2 << endl;
    cout << "c1 == c2: " << boolalpha << (c1 == c2) << endl;

    cout << "c1 + c2 = " << c1 + c2 << endl;
    c1 += c2;
    cout << "c1.real = " << c1.get_real() << endl;
    cout << "c1.imag = " << c1.get_imag() << endl;

    cout << "c1 == c2: " << boolalpha << (c1 == c2) << endl;
}

void test2() {
    using namespace std;

    Complex<int> c1{1, 2}, c2{9, -7};
    ofstream out("ans.txt");
    if(!out.is_open()) {
        cout << "fail to open file ans.txt to write\n";
        return;
    }

    out << "c1 = " << c1 << endl;
    out << "c2 = " << c2 << endl;
    out << "c1 + c2 = " << c1 + c2 << endl;
    out << "(c1 == c2) = " << boolalpha << (c1 == c2) << endl;

    out.close();
    cout << "测试ok!" << endl;
}

任务二:
Contextant.hpp

#pragma once

#include <iostream>
#include <iomanip>
#include <string>

using std::string;
using std::ostream;
using std::istream;
using std::setw;
using std::setprecision;
using std::setiosflags;
using std::ios_base;

// Contestant类声明
class Contestant {
public:
    Contestant() = default;
    ~Contestant() = default;

    int get_num() const { return num; }
    float get_time_usage() const { return time_usage; }

    friend ostream& operator<<(ostream &out, const Contestant &c);
    friend istream& operator>>(istream &in, Contestant &c);

private:
    string no;          // 学号
    string name;        // 姓名
    string major;       // 专业
    int num;            // 解题数
    float time_usage;   // 总用时
};

// 友元函数实现
// 重载流插入运算符<<
ostream& operator<<(ostream &out, const Contestant &c) {
    out << setiosflags(ios_base::left);
    out << setw(15) << c.no
        << setw(15) << c.name
        << setw(15) << c.major
        << setw(5) << c.num
        << setprecision(2) << c.time_usage;
    
    return out;
}

// 重载流提取运算符>>
istream& operator>>(istream &in, Contestant &c) {
    in >> c.no >> c.name >> c.major >> c.num >> c.time_usage;

    return in;
}

utils.hpp

#include "Contestant.hpp"
#include <fstream>
#include <iostream>
#include <string>
#include <vector>

// 排序函数
// 按解题数比较,解题数相同的情况下,按总用时比较,总用时越少,排名越靠前
bool compare_by_solutionInfo(const Contestant &c1, const Contestant &c2) {
    if(c1.get_num() > c2.get_num())
        return true;
    
    if(c1.get_num() == c2.get_num())
        return c1.get_time_usage() < c2.get_time_usage();
    
    return false;
}

// 把vector<Constestant>对象中的元素插入到输出流out
void output(std::ostream &out, const std::vector<Contestant> &v) {
    for(auto &i: v)
        out << i << std::endl;
}


// 把vector<Contestant>对象中的元素写到filename文件中
void save(const std::string &filename, std::vector<Contestant> &v) {
    using std::ofstream;

    ofstream out(filename);
    if(!out.is_open()) {
        std::cout << "fail to open file to write\n";
        return;
    }

    output(out, v);
    out.close();
}

// 从文件filename读取参赛选手信息到vector<Contestant>对象
void load(const std::string &filename, std::vector<Contestant> &v) {
    using std::ifstream;

    ifstream in(filename);
    if(!in.is_open()) {
        std::cout << "fail to open file to read\n";
        return;
    }

    std::string title_line;
    getline(in, title_line);     // 跳过标题行

    int first_column;
    Contestant t;
    while(in >> first_column >> t) 
        v.push_back(t);

    in.close();
}

task2.cpp

#include "Contestant.hpp"
#include "utils.hpp"
#include <iostream>
#include <vector>
#include <algorithm>


void test() {
    using namespace std;

    vector<Contestant> v;

    load("data2.txt", v);   // 从文件加载选手信息到对象v
    sort(v.begin(), v.end(), compare_by_solutionInfo);  // 按解题情况排序
    output(cout, v);    // 输出对象v中信息到屏幕
    save("ans.txt", v); // 把对象v中选手信息保存到文件
}

int main() {
    test();
}

任务三:
Triangle.hpp

#include <iostream>
#include <stdexcept>
#include <cmath>

using namespace std;

class Triangle {
public:
    Triangle(double s1, double s2, double s3);
    ~Triangle() = default;

    double area() const;

private:
    double a, b, c;
};

Triangle::Triangle(double s1, double s2, double s3): a{s1}, b{s2}, c{s3} {
    if(a <= 0 || b <= 0 || c <= 0)
        throw invalid_argument("边长出现负值");
        
    if(a+b <= c || b+c <= a || a+c <= b) 
        throw invalid_argument("不满足任意两边之和大于第三边");
}

double Triangle::area() const {
    double s = (a + b + c)/2;
    return sqrt(s*(s-a)*(s-b)*(s-c));
}

task3.cpp

#include "Triangle.hpp"
#include <iostream>
#include <fstream>

void test() {
    using namespace std;

    cout << "从文件读入三角形三边边长,计算面积" << endl;

    ifstream in("data3.txt");
    if(!in.is_open()) {
        cout << "fail to open file to read\n";
        return;
    }

    double a,b,c;
    do {
        cout << "三角形边长: ";
        in >> a >> b >> c;
        cout << a << " " << b << " " << c << endl;

        try {
            Triangle t(a, b, c);
            cout << "三角形面积: " << t.area() << endl << endl;
        }catch(const exception &e) {
            cout << "error: " << e.what() << endl << endl;
        }

        if(in.peek() == EOF)
            break;
    } while(1);

    in.close();
}

int main() {
    test();
}

 任务四:

Vector

#include<iostream>
#include<stdexcept>

using namespace std;

template<typename T>
class Vector{
    private:
        int size;
        T *ptr;
    public:
        Vector(int s):size(s){
            if(s<0)
                throw length_error("Vector constructor:negative size"); 
            else
                ptr=new T[size];
        }
        Vector(int s,T value):size(s){
            if(s<0)
                throw length_error("Vector constructor:negative size"); 
            else
            {
                ptr=new T[size];
                for(int i=0;i<s;i++)
                    *(ptr+i)=value;
            }
        }
        Vector(const Vector<T> &v){
            size=v.size;
            ptr=new T[size];
            for(int i=0;i<size;i++)
                *(ptr+i)=v.ptr[i];
        }
        ~Vector(){delete []ptr;}
        int get_size();
        T& at(int index);
        T& operator[](int index);
        friend void output(Vector<T> v){
            for(int i=0;i<v.size;i++)
                cout<<v.ptr[i]<<",";
            cout<<endl;
        }
};

template<typename T>
int Vector<T>::get_size(){return size;} 

template<typename T>
T& Vector<T>::at(int index){
    if (index<0||index>=size)
        throw out_of_range("Vector:index out of range");
    return *(ptr+index);
}

template<typename T>
T& Vector<T>::operator[](int index){                                                                                                                         
    if (index<0||index>=size)
        throw out_of_range("Vector:index out of range");
    return *(ptr+index);
}

task4.cpp

#include <iostream>
#include "Vector.hpp"

void test1() {
    using namespace std;

    int n;
    cout << "Enter n: ";
    cin >> n;
    
    Vector<double> x1(n);
    for(auto i = 0; i < n; ++i)
        x1.at(i) = i * 0.7;

    cout << "x1: "; output(x1);

    Vector<int> x2(n, 42);
    const Vector<int> x3(x2);

    cout << "x2: "; output(x2);
    cout << "x3: "; output(x3);

    x2.at(0) = 77;
    x2.at(1) = 777;
    cout << "x2: "; output(x2);
    cout << "x3: "; output(x3);
}

void test2() {
    using namespace std;

    int n, index;
    while(cout << "Enter n and index: ", cin >> n >> index) {
        try {
            Vector<int> v(n, n);
            v.at(index) = -999;
            cout << "v: "; output(v);
        }
        catch (const exception &e) {
            cout << e.what() << endl;
        }
    }
}

int main() {
    cout << "测试1: 模板类接口测试\n";
    test1();

    cout << "\n测试2: 模板类异常处理测试\n";
    test2();
}

任务五:

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <tuple>
#include <algorithm>
#include <string>

struct Student {
    int id;
    std::string name;
    std::string major;
    int score;
};

bool operator<(const Student& a, const Student& b) {
    if (a.major == b.major) {
        return a.score > b.score;
    }
    return a.major < b.major; 
}

std::vector<Student> readStudentsFromFile(const std::string& filename) {
    std::vector<Student> students;
    std::ifstream file(filename);
    std::string line;
    std::getline(file, line);
    while (std::getline(file, line)) {
        std::istringstream iss(line);
        Student student;
        iss >> student.id >> student.name >> student.major >> student.score;
        students.push_back(student);
    }
    file.close();
    return students;
}

void writeStudentsToFile(const std::vector<Student>& students, const std::string& filename) {
    std::ofstream file(filename);
    for (const auto& student : students) {
        file << student.id << "\t" << student.name << "\t" << student.major << "\t" << student.score << std::endl;
    }
    file.close();
}

int main() {
    std::vector<Student> students = readStudentsFromFile("data5.txt");
    std::sort(students.begin(), students.end());
    std::cout << "学号\t姓名\t专业\t分数" << std::endl;
    for (const auto& student : students) {
        std::cout << student.id << "\t" << student.name << "\t" << student.major << "\t" << student.score << std::endl;
    }
    writeStudentsToFile(students, "ans5.txt");
    return 0;
}

 

标签:std,文件,const,get,Complex,实验,return,include,模板
From: https://www.cnblogs.com/luyiming/p/18619011

相关文章

  • 实验六
    task4代码Vector.hpp点击查看代码#pragmaonce#include<iostream>#include<stdexcept>usingnamespacestd;template<typenameT>classVector{public:Vector(intsize,intvalue=0):size{size}{if(size<0)throwlengt......
  • 实验6 模板类、文件I/O和异常处理
    任务一Complex.hpp#pragmaonce#include<iostream>#include<stdexcept>//声明//////////////////////////////////////////////////////复数模板类声明template<typenameT>classComplex{public:Complex(Tr=0,Ti=0);Complex(const......
  • 实验六
    task4源代码:#include<stdio.h>#defineN10typedefstruct{charisbn[20];//isbn号charname[80];//书名charauthor[80];//作者doublesales_price;//售价intsales_count;//销售册数}Book;......
  • 实验六 C++
    任务四:Vector.hpp:#pragmaonce#ifndefVECTOR_HPP#defineVECTOR_HPP#include<iostream>#include<stdexcept>//为异常类提供支持#include<memory>//为std::unique_ptr提供支持template<typenameT>classVector{private:std::uniqu......
  • 隐藏文件夹命名规则:程序员必知的文件夹可见性模式
    隐藏文件夹命名规则:程序员必知的文件夹可见性模式在开发过程中,你可能会发现一些文件夹名称非常特别,通常以点(.)开头,例如.git、.venv、.env等。这些文件夹通常包含项目的配置信息、版本控制数据或者虚拟环境等,虽然它们在项目中扮演着重要的角色,但它们常常是隐藏的,这引......
  • VR展厅模板在各种平台上运行效果如何?
    随着虚拟现实(VR)技术的快速发展,VR展厅模板已成为企业和个人展示产品、艺术作品或项目的新选择。这些模板以其沉浸式体验和互动性受到市场的欢迎。然而,用户可能会关心这些模板在不同平台上的运行效果。接下来,由专业从事VR展厅模板设计的圆桌3D云展厅平台将探讨VR展厅模板在各种......
  • 大型数据库应用技术:实验1 熟悉常用的Linux操作和Hadoop操作
    实验1熟悉常用的Linux操作和Hadoop操作1.实验目的Hadoop运行在Linux系统上,因此,需要学习实践一些常用的Linux命令。本实验旨在熟悉常用的Linux操作和Hadoop操作,为顺利开展后续其他实验奠定基础。2.实验平台(1)操作系统:Linux(建议Ubuntu16.04或Ubuntu18.04);(2)Hadoop版本:3.1.3。3.......
  • 实验6
    任务一1#include<stdio.h>2#include<string.h>3#defineN34typedefstructstudent{5intid;6charname[20];7charsubject[20];8doubleperf;9doublemid;......
  • 实验6 模板类、文件I/O和异常处理
    实验任务41#ifndefVECTOR_HPP2#defineVECTOR_HPP34#include<iostream>5#include<stdexcept>67template<typenameT>8classVector{9private:10T*data;11size_tsize;1213public:14//构造函数,动态指定大小15......
  • 百度机器翻译SDK实验
    软件构造实验作业实验名称:班级:信2205-3    学号:20223753    姓名:邓睿智 实验一:百度机器翻译SDK实验一、实验要求实验一:百度机器翻译SDK实验(2024.11.15日完成)  任务一:下载配置百度翻译Java相关库及环境(占10%)。    任务二:了解百度翻译相关功能并进行总结......