实验4 现代C++标准库与类模板

发布时间 2023-11-27 10:51:15作者: LE_SH

实验任务1

源代码:

#include <iostream>

using std::cout;
using std::endl;

// 类A的定义
class A{
public:
    A(int x0, int y0): x{ x0 }, y{ y0 } {}
    void show() const { cout << x << ", " << y << endl; }
private:
    int x, y;
};

// 类B的定义
class B{
public:
    B(double x0, double y0): x{ x0 }, y{ y0 } {}
    void show() const { cout << x << ", " << y << endl;}
private:
    double x, y;
};

void test() {
    cout << "测试类A: " << endl;
    A a(3, 4);
    a.show();

    cout << "\n测试类B: " << endl;
    B b(3.2, 5.6);
    b.show();
}

int main() {
    test();
}
task1_1

运行结果:

源代码:

#include <iostream>
#include <string>

using std::cout;
using std::endl;

// 定义类模板X
template<typename T>
class X{
public:
    X(T x0, T y0): x{x0}, y{y0} {}
    void show() const { cout << x << ", " << y << endl;}
private:
    T x, y;
};

void test() {
    cout << "测试1: 模板类抽象类型T用int实例化" << endl;
    X<int> x1(3, 4);
    x1.show();

    cout << "\n测试2: 模板类抽象类型T用double实例化" << endl;
    X<double> x2(3.2, 5.6);
    x2.show();

    cout << "\n测试3: 模板类抽象类型T用标准库中的string实例化" << endl;
    X<std::string> x3("hello", "c plus plus");
    x3.show();
}

int main() {
    test();
}
task1_2

运行结果:

 

实验任务2

源代码:

#include <iostream>
#include <string>
#include <limits>

using namespace std;

int main() {
    

    const int n = 10;
    string prompt = string(n, '*') + "Enter a string: " + string(n, '*') + '\n';

    cout << "测试1:";
    cout << prompt;
    string s1;
    cin >> s1;  // 从输入流中提取字符串给s1,碰到空格、回车、Tab键即结束
    cout << "s1: " << s1 << endl;
    cin.ignore(numeric_limits<streamsize>::max(), '\n');  // 清空输入缓冲区

    cout << "\n测试2:";
    cout << prompt;
    getline(cin, s1);  // 从输入流中提取一行字符串给s1,直到换行
    cout << "s1: " << s1 << endl;

    cout << "\n测试3:";
    string s2, s3;
    cout << prompt;
    getline(cin, s2, ' ');  // 从输入流中提取字符串给s2,直到指定分隔符空格
    getline(cin, s3);
    cout << "s2: " << s2 << endl;
    cout << "s3: " << s3 << endl;
}
task2_1

运行结果:

源代码:

#include <iostream>
#include <string>

int main() {
    using namespace std;

    string s;

    cout << "Enter words: \n";
    // 重复录入字符串,将小写字符转换成大写,直到按下Ctrl+Z
    while( getline(cin, s) ) {
        for(auto &ch: s)
            ch = toupper(ch);
        cout << s << "\n";
    }
}
task2_2

运行结果:

源代码:

#include <iostream>
#include <string>
#include <algorithm>

int main() {
    using namespace std;

    string s1;

    cout << "Enter words: \n";
    getline(cin, s1);
    cout << "original words: \n";
    cout << s1 <<endl;
    cout << "to uppercase: \n";
    transform(s1.begin(), s1.end(), s1.begin(), ::toupper);
    cout << s1 << endl;
}
task2_3

运行结果:

源代码:

#include <iostream>
#include <string>

int main() {
    using namespace std;

    string s1, s2;
    s1 = "nuist";                                 // 赋值
    s1[0] = 'N';                                  // 支持通过[]和索引方式访问
    s1.at(1) = 'U';                               // 支持通过xx.at()方法访问
    cout << boolalpha << (s1 == "nuist") << endl; // 字符串比较
    cout << s1.length() << endl;                  // 字符串长度
    cout << s1.size() << endl;                    // 字符串长度
    s2 = s1 + ", 2050";                           // 字符串连接
    cout << s2 << endl;

    string email{"xyz@gmail.com"};
    auto pos = email.find("@"); // 查找子串"@"第一次出现的索引位置,如果失败,返回string::npos
    if (pos == string::npos)
        cout << "illegal email address";
    else {
        auto s1 = email.substr(0, pos);  // 取子串, 从索引0 ~ pos-1
        auto s2 = email.substr(pos + 1); // 取子串,从pos+1到末尾
        cout << s1 << endl;
        cout << s2 << endl;
    }

    string phone{"15216982937"};
    cout << phone.replace(3, 5, string(5, '*')) << endl; // 把从索引位置为3开始的连续5个字符替换成*

    string s3{"cosmos"}, s4{"galaxy"};
    cout << "s3: " + s3 + " s4: " + s4 << endl;
    s3.swap(s4); // 交换
    cout << "s3: " + s3 + " s4: " + s4 << endl;

    string s5{"abc"};
    const char *pstr = s5.c_str(); // 方法c_str()把string类字符串组转换成C风格的字符串
    cout << pstr << endl;

    string s6{"12306"};
    int x1 = stoi(s6); // 把string转换成int
    cout << x1 << endl;

    int x2 = 12306;
    string s7 = to_string(x2);  // 把int转换成string
    cout << s7 << endl;

    double x3 = 123.06;
    string s8 = to_string(x3); // 把double转换成string
    cout << s8 << endl;
}
task2_4

运行结果:

 

实验任务3

源代码:

#include <iostream>
#include <vector>


template<typename T>
void output(const T &obj) {
    for(auto &item: obj)
        std::cout << item << ", ";
    std::cout << "\b\b \n";
}

int main() {
    using namespace std;

    vector<int> v1;                // 创建一个vector对象v1, 未指定大小, 元素是int型, 未初始化
    vector<int> v2(5);             // 创建一个vector对象v2, 包含5个元素,元素是int型,初始值是默认值0
    vector<int> v3(5, 42);         // 创建一个vector对象v3, 包含5个元素,元素是int型,指定初始值是42
    vector<int> v4{1, 9, 8, 4}; // 创建一个vector对象v4, 元素是int型,使用初始化列表方式
    vector<int> v5{v4};            // 创建一个vector对象v5, 使用已经存在的对象v4创建

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

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

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

    cout << "v5: ";
    output(v5);
}
task3_1

运行结果:

源代码:

#include <iostream>
#include <vector>

using std::cout;
using std::endl;
using std::vector;

void output(const vector<int> &v) {
    cout << "v.size() = " << v.size() << endl;
    cout << "v.capacity() = " << v.capacity() << endl;
    cout << endl;
}

int main() {
    vector<int> v{42};
    output(v);

    v.push_back(55);
    v.push_back(90);
    output(v);

    for(auto i = 0; i < 8; ++i)
        v.push_back(i);
    output(v);

    v.pop_back();
    output(v);
}
task3_2

 

实验任务4

源代码:

#include <iostream>
#include <vector>
#include <array>
#include <string>
#include <algorithm>

using namespace std;

// 函数模板
// 通过索引方式输出对象值
template<typename T>
void output1(const T &obj) {
    for(auto i = 0; i < obj.size(); ++i)
        cout << obj.at(i) << ", ";
    cout << "\b\b \n";
}

// 函数模板
// 通过迭代器方式输出对象值
template<typename T>
void output2(const T &obj) {
    for(auto p = obj.cbegin(); p != obj.cend(); ++p)
        cout << *p << ", ";
    cout << "\b\b \n";
}

// 函数模板
// 通过auto for方式输出对象值
template<typename T>
void output3(const T &obj) {
    for(auto &item: obj) 
        cout << item << ", ";
    cout << "\b\b \n";
}

// 测试string类对象
void test1() {
    string s1{"cplus"};

    output1(s1);

    reverse(s1.begin(), s1.end());  // 对对象s1中的数据项进行翻转
    output2(s1);

    sort(s1.begin(), s1.end());   // 对对象s1中的数据项排序(默认升序)
    output3(s1);
}

// 测试array<int>类对象
void test2() {
    array< array<int, 4>, 3> x{1, 9, 8, 4, 2, 0, 2, 3, 2, 0, 4, 9 };

    output1( x.at(0) );
    output2( x.at(1) );
    output3( x.at(2) );
}

// 测试vector<string>类对象
void test3() {
    vector<string> v1 {"Sheldon", "Leonard", "Howard", "Raj"};

    v1.push_back("Penny");
    v1.push_back("Amy");

    output1(v1);

    sort(v1.begin(), v1.end(), std::greater<string>());  // 对v1对象中的字符串按降序排序
    output2(v1);

    reverse(v1.begin(), v1.end());  // 对v1对象中的字符串翻转
    output3(v1);
}

int main() {
    cout << "测试1: " << endl;
    test1();

    cout << "测试2: " << endl;
    test2();

    cout << "测试3: " << endl;
    test3();
}
task4

运行结果:

 

实验任务5

源代码:

#include "textcoder.hpp"
#include <iostream>
#include <string>

void test() {
    using namespace std;

    string text, encoded_text, decoded_text;

    cout << "输入英文文本: ";
    while (getline(cin, text)) {
        TextCoder coder(text);

        encoded_text = coder.get_ciphertext();  
        cout << "加密后英文文本:\t" << encoded_text << endl;

        decoded_text = coder.get_deciphertext(); 
        cout << "解密后英文文本:\t" << decoded_text << endl;
        cout << "\n输入英文文本: ";
    }
}

int main() {  
    test(); 
    return 0;
}
task5.cpp
#include "textcoder.hpp"

TextCoder::TextCoder(const std::string& input_text) : text(input_text) {}

void TextCoder::encoder() {
    for (char& c : text) {
        if (isalpha(c)) {
            if (islower(c)) {
                c = ((c - 'a' + 7) % 26) + 'a';
            } else {
                c = ((c - 'A' + 7) % 26) + 'A';
            }
        }
    }
}

void TextCoder::decoder() {
    for (char& c : text) {
        if (isalpha(c)) {
            if (islower(c)) {
                c = ((c - 'a' - 7 + 26) % 26) + 'a';
            } else {
                c = ((c - 'A' - 7 + 26) % 26) + 'A';
            }
        }
    }
}

std::string TextCoder::get_ciphertext() {
    encoder();
    return text;
}

std::string TextCoder::get_deciphertext() {
    decoder();
    return text;
}
textcoder.cpp
#ifndef TEXTCODER_HPP
#define TEXTCODER_HPP

#include <string>

class TextCoder {
private:
    std::string text;

    void encoder();
    void decoder();

public:
    TextCoder(const std::string& input_text);

    std::string get_ciphertext();
    std::string get_deciphertext();
};

#endif
textcoder.hpp

运行结果:

 

实验任务6

源代码:

#include <iostream>
#include <vector>
#include <limits>

#include "info.hpp"

int main() {
    const int capacity = 100; 

    std::vector<Info> audience_info_list;

    std::cout << "开始录入预约信息,请输入预约听众的信息,输入-1停止录入:" << std::endl;

    int totalReserved = 0;

    while (true) {
        std::string nickname, contact, city;
        int n;

        std::cout << "昵称: ";
        std::cin >> nickname;

        if (nickname == "-1") {
            break;
        }

        std::cout << "联系方式: ";
        std::cin >> contact;

        std::cout << "所在城市: ";
        std::cin >> city;

        std::cout << "预定参加人数: ";
        while (true) {
            std::cin >> n;

            if (n <= 0) {
                std::cout << "预定参加人数必须大于0,请重新输入: ";
                std::cin.clear();
                std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
            } else {
                break;
            }
        }

        if (totalReserved + n <= capacity) {
            audience_info_list.emplace_back(nickname, contact, city, n);
            totalReserved += n;
            std::cout << "预约成功!" << std::endl;
        } else {
            std::cout << "livehouse容量不足,总预约人数已达上限。" << std::endl;
            std::cout << "输入 'q' 退出预定,输入 'u' 更新预定信息: ";
            char choice;
            std::cin >> choice;

            if (choice == 'q') {
                break;
            } else if (choice == 'u') {
                std::cout << "更新预定信息..." << std::endl;
            }
        }
    }

    std::cout << "所有预约听众信息:" << std::endl;
    for (const auto& info : audience_info_list) {
        info.print();
    }

    return 0;
}
task6.cpp
#ifndef INFO_HPP
#define INFO_HPP

#include <iostream>
#include <string>

class Info {
public:
    Info(const std::string& nickname, const std::string& contact, const std::string& city, int n);

    void print() const;

private:
    std::string nickname_;
    std::string contact_;
    std::string city_;
    int n_;
};

#endif 
info.hpp
#include "info.hpp"

Info::Info(const std::string& nickname, const std::string& contact, const std::string& city, int n)
    : nickname_(nickname), contact_(contact), city_(city), n_(n) {}

void Info::print() const {
    std::cout << "昵称: " << nickname_ << ", 联系方式: " << contact_
              << ", 所在城市: " << city_ << ", 预定参加人数: " << n_ << std::endl;
}
info.cpp

运行结果: