测试_第06章_字符串与IO.cpp

← 测试总览 · 目录

编译运行:clang++ -std=c++26 -Wall -Wextra -pthread 测试_第06章_字符串与IO.cpp -o t && ./t(需先 cd 测试/

// 第6章测试:字符串与输入输出
#include <print>
#include <string>
#include <string_view>
#include <format>
#include <fstream>
#include <sstream>
#include <cstdio>

int failures = 0;
#define CHECK(expr)                                                         \
    do {                                                                    \
        if (!(expr)) {                                                      \
            ++failures;                                                     \
            std::println("FAIL 第{}行: {}", __LINE__, #expr);              \
        }                                                                   \
    } while (0)

int main() {
    // 6.1 基础操作
    std::string s = "hello";
    std::string t = "world";
    std::string u = s + " " + t;
    CHECK(u == "hello world");
    s += "!";
    CHECK(s == "hello!");
    CHECK(s.size() == 6);
    CHECK(s[0] == 'h');

    // 6.2 常用方法
    CHECK(u.substr(6, 5) == "world");
    CHECK(u.find("lo") == 3);
    CHECK(u.find("zzz") == std::string::npos);
    CHECK(u.starts_with("hello"));
    CHECK(u.ends_with("world"));
    CHECK(u.contains("ello"));
    std::string r = "0123456789";
    r.replace(2, 3, "AB");
    CHECK(r == "01AB56789");
    r.insert(0, ">>");
    CHECK(r == ">>01AB56789");
    r.erase(0, 2);
    CHECK(r == "01AB56789");
    r.push_back('!');
    CHECK(r.back() == '!');

    // 6.3 数字转换
    int n = std::stoi("42");
    CHECK(n == 42);
    double d = std::stod("3.14");
    CHECK(d > 3.13 && d < 3.15);
    std::string fmt = std::format("{}", 42);
    CHECK(fmt == "42");
    std::string pad = std::format("{:06.2f}", 3.14159);
    CHECK(pad == "003.14");
    std::string hex = std::format("{:#x}", 255);
    CHECK(hex == "0xff");
    std::string bin = std::format("{:b}", 5);
    CHECK(bin == "101");

    // 6.4 string_view
    std::string full = "hello world";
    std::string_view sv(full.data() + 6, 5);
    CHECK(sv == "world");
    CHECK(sv.size() == 5);
    // sv 不拥有数据:full 改引用内容会"看到变化"(视图特性)
    CHECK(sv.starts_with("wor"));

    // 6.5 格式化宽度对齐
    std::string right = std::format("{:>6}", "abc");
    CHECK(right == "   abc");
    std::string left = std::format("{:<6}", "abc");
    CHECK(left == "abc   ");
    std::string zerof = std::format("{:05d}", 42);
    CHECK(zerof == "00042");

    // 6.7 输入:用字符串流模拟终端输入(cin 同族)
    std::istringstream in("42 3.14 hello");
    int iv;
    double dv;
    std::string sv2;
    in >> iv >> dv >> sv2;
    CHECK(iv == 42 && dv > 3.13 && dv < 3.15 && sv2 == "hello");

    // getline 整行
    std::istringstream in2("第一行\n第二行\n");
    std::string line;
    std::getline(in2, line);
    CHECK(line == "第一行");
    std::getline(in2, line);
    CHECK(line == "第二行");

    // 6.8 文件读写(用临时文件验证)
    const char* fname = "/tmp/io_test.txt";
    {
        std::ofstream out(fname);
        out << "hello " << 42 << '\n';
    }
    {
        std::ifstream in3(fname);
        std::string word;
        std::string all;
        while (in3 >> word) all += word + "|";
        CHECK(all == "hello|42|");
    }
    std::remove(fname);

    // 6.8b 读整个文件
    {
        std::ofstream out(fname);
        out << "line1\nline2\n";
    }
    {
        std::ifstream in4(fname);
        std::string content((std::istreambuf_iterator<char>(in4)),
                             std::istreambuf_iterator<char>());
        CHECK(content == "line1\nline2\n");
    }
    std::remove(fname);

    // 文件打不开检测
    {
        std::ifstream bad("/no/such/file/xyz");
        CHECK(!bad);
    }

    if (failures == 0) std::println("全部通过");
    return failures;
}