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

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

时间:2023-12-13 15:57:23浏览次数:30  
标签:std 文件 const get Complex 实验 include 模板 size

实验任务1

源代码:

#pragma once

#include <iostream>
#include <stdexcept>


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

    T get_real() const { return real; }
    T get_imag() const { return imag; }

    // 成员函数声明, 重载+=为模板类Complex成员函数
    Complex<T>& operator+=(const Complex<T> c);    


    // 友元函数声明, 重载流插入运算符<<和提取运算符>>为模板类Complex的友元函数
    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;
    T 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>::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();
}
Complex.hpp
#include "Complex.hpp"
#include <iostream>
#include <fstream>
#include <stdexcept>

// 测试1:复数模板类测试
void test1() {
    using namespace std;

    Complex<double> c1{1, 2}, c2;
    
    cout << "Enter c2: ";
    cin >> c2;
    cout << "c1 = " << c1 << endl;
    cout << "c2 = " << 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 << boolalpha << (c1 == c2) << endl;
}

// 测试2:文件流提取>>和插入<<运算符测试
void test2() {
    using namespace std;

    Complex<int> c1{1, 5}, c2{3, -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.close(); 
}


int main() {
    using namespace std;

    cout << "测试自定义复数模板类Complex<T>..." << endl;
    test1();

    cout << "\n测试文件流I/O..." << endl;
    test2();
}
task1.cpp

运行结果:

 

实验任务2

源代码:

#pragma once

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

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


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

    string get_name() const { return name; }
    string get_no() const { return no; }
    int get_score() const { return score; }

    friend ostream& operator<<(ostream &out, const STU &s);
    friend istream& operator>>(istream &in, STU &s);

private:
    string no;
    string name;
    int score;
};

// 友元函数实现
// 流插入运算符<<重载函数
ostream& operator<<(ostream &out, const STU &s) {
    out << setiosflags(ios_base::left) << setw(15) << s.no
        << setw(15) << s.name
        << s.score;

    return out;
}

// 流提取运算符>>重载函数
istream& operator>>(istream &in, STU &s) {
    in >> s.no >> s.name >> s.score;

    return in;
}
stu.hpp
#include "stu.hpp"
#include "utils.hpp"

#include <vector>
#include <fstream>
#include <algorithm>

void test1() {
    using namespace std;

    vector<STU> stu;
    STU t;

    // 从文件读取学生信息到vector<STU>对象stu中
    ifstream in;
    in.open("data.txt", ios::in);
    if(!in.is_open()) {
        cout << "fail to open file data.txt\n";
        return;
    }

    while(in >> t)
        stu.push_back(t);
    
    in.close();

    // 输出原始学生信息到屏幕
    cout << "\n原始学生信息:\n";
    output(cout, stu);

    // 按学号升序排序,把结果保存到文件data_by_no.txt
    sort(stu.begin(), stu.end(), compare_by_no);
    save("data_by_no.txt", stu);

    // 按姓名升序排序,把结果保存到文件data_by_name.txt
    sort(stu.begin(), stu.end(), compare_by_name);
    save("data_by_name.txt", stu);

    // 按分数降序排序,把结果保存到文件data_by_score.txt
    sort(stu.begin(), stu.end(), compare_by_score);
    save("data_by_score.txt", stu);

}

int main() {
    test1();
}
task2.cpp
#include "stu.hpp"
#include <vector>
#include <fstream>
#include <iostream>
#include <string>

// 按姓名字典序比较,s1姓名在字典前面,返回True
bool compare_by_name(const STU &s1, const STU &s2) {
    return s1.get_name() < s2.get_name();
}
// 按学号字典序比较,s1学号在字典前面,返回True
bool compare_by_no(const STU &s1, const STU &s2) {
    return s1.get_no() < s2.get_no();
}

// 按分数比较,s1分数高于s2分数,返回True
bool compare_by_score(const STU &s1, const STU &s2) {
    return s1.get_score() > s2.get_score();
}

// 把动态STU数组对象中的元素插入输出流out中
void output(std::ostream &out,  std::vector<STU> &v) {
    for(auto &i: v)
        out << i << std::endl;
}

// 把动态STU数组对象中的元素保存到文件名为filename的文件中
void save(std::string filename, std::vector<STU> &v) {
    using std::ofstream;

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

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

运行结果:

 

实验任务3

源代码:

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

void test1() {
    using namespace std;

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

    ifstream in("triangle_data.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() {
    test1();
}
task3.cpp
#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));
}
Triangle.hpp

运行结果:

 

实验任务4

源代码:

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

void test() {
    using namespace std;

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

    output(x1);

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

    output(x2);
    output(x3);

    x2.at(0) = 77;
    output(x2);

    x3[0] = 999;
    output(x3);
}

int main() {
    test();
}
task4.cpp
#ifndef VECTOR_HPP
#define VECTOR_HPP

#include <iostream>
#include <stdexcept>

using namespace std;

template <typename T>
class Vector {
private:
    T* data; 
    size_t size; 

public:
    Vector(size_t sz) : size(sz) {
        data = new T[size];
    }

    Vector(size_t sz, const T& value) : size(sz) {
        data = new T[size];
        for (size_t i = 0; i < size; ++i) {
            data[i] = value;
        }
    }

    Vector(const Vector& other) : size(other.size) {
        data = new T[size];
        for (size_t i = 0; i < size; ++i) {
            data[i] = other.data[i];
        }
    }

    ~Vector() {
        delete[] data;
    }

    size_t get_size() const {
        return size;
    }

    T& at(size_t index) {
        if (index < size) {
            return data[index];
        } else {
            throw out_of_range("Index out of range");
        }
    }

    T& operator[](size_t index) {
        if (index < size) {
            return data[index];
        } else {
            throw out_of_range("Index out of range");
        }
    }

    friend void output(const Vector& vec) {
        for (size_t i = 0; i < vec.size; ++i) {
            cout << vec.data[i] << ' ';
        }
        cout << endl;
    }
};

#endif 
Vector.hpp

运行结果:

 

实验任务5

源代码:

#include <iostream>
#include <iomanip>
#include <fstream>

using namespace std;

void output(ostream &out) {
    const int numLines = 26;

    for (int i = 0; i < numLines; ++i) {
        out << setw(2) << right << i + 1 << ' '; 
        for (int j = 0; j < 26; ++j) {
            char ch = 'A' + (i + j) % 26;
            out << ch << ' '; 
        }
        out << endl;
    }
}

int main() {
    cout << "屏幕上打印输出:\n" 
         << "   a b c d e f g h i j k l m n o p q r s t u v w x y z" 
         << endl;
    output(cout);

    ofstream outFile("cipher_key.txt");
    if (outFile.is_open()) {
        cout << "写入文件 cipher_key.txt:" << endl;
        output(outFile);
        outFile.close();
    } else {
        cerr << "无法打开文件 cipher_key.txt" << endl;
        return 1;
    }

    return 0;
}
task5.cpp

运行结果:

 

标签:std,文件,const,get,Complex,实验,include,模板,size
From: https://www.cnblogs.com/le-sh/p/17893774.html

相关文章

  • 01C# 从Json文件中读取配置
    目的:从Json文件中读取配置 1)创建一个json文件,设置“如果较新则复制”{"Smtp":{"Server":"yx165.com","Name":"yx","Password":"123456"},"Person":{"Name":"......
  • UBUNTU 18.04.6 在编译linux内核的时候执行make ARCH=arm socfpga_defconfig设置默认
    在编译linux内核的时候执行makeARCH=armsocfpga_defconfig设置默认配置时报错bisonflexnotfound缺少文件:/bin/sh:1:bison:notfound 输入命令sudoapt-getinstallbison进行安装: /bin/sh:1:flex:notfound 输入命令 sudoapt-getinstallflex进行安......
  • 台达 通讯出现 DriverInf.txt文件丢失 方便别人
    DriverInf.txt文件丢失是因为计算机使用了mindmanager6免安装版本而把登入文件里面的msxmldll路径修改掉造成有使用到msxmlDLL的所有应用程序都会发生问题.下载链接:DownloadKB2758694:MicrosoftXMLCoreServices4.0ServicePack3安全性更新fromOfficialMicrosoft......
  • k8s配置文件管理
    1.为什么要用configMapConfigMap是一种用于存储应用所需配置信息的资源类型,用于保存配置数据的键值对,可以用来保存单个属性,也可以用来保存配置文件。通过ConfigMap可以方便的做到配置解耦,使得不同环境有不同的配置。考虑真实的使用场景,像数据库这类中间件,是作为公共资源,为多个......
  • 【Python爬虫】Scrapy框架文件写入方式CSV,MYSQL,MongoDB_爬取新浪彩票双色球
    Spider代码爬取新浪彩票双色球页面数据,只爬取期号、红球、篮球classShuangseqiu11Spider(scrapy.Spider):name="shuangseqiu11"allowed_domains=["sina.com.cn"]start_urls=["https://view.lottery.sina.com.cn/lotto/pc_zst/index?lottoType=ssq&......
  • javaWeb项目开发文件上传与下载功能实现
    Web开发文件上传与下载依赖<!--java生成excel文件插件--><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.15</version></dependency><!--文件上传--><dependency><g......
  • Java-jdk 11或17 文件路径中没有jre文件
    Java-jdk11或17文件路径中没有jre文件 简介: Java-jdk11或17文件路径中没有jre文件在使用IDE敲代码的时候,是需要安装jdk的。但是由于jdk版本的不同导致在配置系统环境的时候找不到对应的jre文件。    所以我们想要配置系统变量就需要有jre文件,j......
  • kubesphere 的 流水线maven 模板缺少 kubectl解决
    最开始解决方案是maven的pod里通过在线下载kubectl命令 发现每次构建后端服务,都去官网下载kubectl命令相当慢。既然用到maven模板,遂将master节点的kubectl命令通过hostpath挂载到maven的pod模板里面。问题解决。 agent模板cm配置【jenkins-casc-config】在【kubes......
  • UBUNTU 18.04.6 的Quartus里面转换sof到rbf文件在uboot阶段加载时出错或者在kernel启
    参考Intel的SD卡image设计的教程(https://rocketboards.org/foswiki/Documentation/EmbeddedLinuxBeginnerSGuide) 确认DE10-Nano的MSEL设置为01010,插上SD卡 给DE10-Nano上电,发现可以启动,但卡死在这里不动了: 如果只测试Preloader和uboot的时候也有这个错误: ......
  • 通过excel表格批量修改文件夹名称
    脚本功能这个脚本用于重命名文件夹,特别是在多层嵌套的文件夹结构中。它通过读取一个Excel表格来获取重命名的信息。表格的第一列应包含当前的文件夹名称,第二列包含您想要更改为的新名称。脚本会递归地遍历指定路径下的所有文件夹,并根据表格中的信息重命名匹配的文件夹。 impo......