编译运行: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;
}