本章目标:三个完整可运行的项目,覆盖大部分知识点。 每个项目都给出完整代码,请亲手敲一遍、改一遍、跑一遍。
功能:读入文本文件,统计每个单词出现次数,输出 TOP 10。 知识点:文件 IO、string、map、sort、lambda、format。
#include <print>
#include <fstream>
#include <string>
#include <map>
#include <vector>
#include <algorithm>
#include <cctype>
int main(int argc, char* argv[]) {
if (argc < 2) {
std::println("用法:./wordfreq 文件名");
return 1;
}
std::ifstream in(argv[1]);
if (!in) {
std::println("打不开文件:{}", argv[1]);
return 1;
}
std::map<std::string, int> freq;
std::string word;
while (in >> word) {
std::string clean;
for (char c : word) {
if (std::isalpha(static_cast<unsigned char>(c)))
clean.push_back(std::tolower(static_cast<unsigned char>(c)));
}
if (!clean.empty()) ++freq[clean];
}
std::vector<std::pair<std::string, int>> items(freq.begin(), freq.end());
std::sort(items.begin(), items.end(),
[](const auto& a, const auto& b) {
return a.second > b.second; // 次数降序
});
std::println("单词总数:{},不同单词:{}", freq.size(), items.size());
for (int i = 0; i < 10 && i < (int)items.size(); ++i) {
std::println("{:>4}. {:<15} {}", i + 1, items[i].first, items[i].second);
}
}
运行:
clang++ -std=c++26 wordfreq.cpp -o wordfreq
./wordfreq 06_字符串与输入输出.txt
功能:增删查改任务,支持优先级排序,保存到文件。 知识点:struct、vector、optional、variant、错误处理、序列化。
#include <print>
#include <string>
#include <vector>
#include <fstream>
#include <iostream>
#include <optional>
#include <algorithm>
struct Task {
std::string title;
int priority = 0; // 0 最低,5 最高
bool done = false;
};
using TaskList = std::vector<Task>;
void save(const TaskList& tasks, const std::string& file) {
std::ofstream out(file);
for (const auto& t : tasks)
out << t.done << ' ' << t.priority << ' ' << t.title << '\n';
}
std::optional<TaskList> load(const std::string& file) {
std::ifstream in(file);
if (!in) return std::nullopt;
TaskList tasks;
Task t;
while (in >> t.done >> t.priority) {
std::getline(in, t.title);
if (!t.title.empty() && t.title.front() == ' ')
t.title.erase(0, 1); // 去掉开头空格
tasks.push_back(t);
}
return tasks;
}
void show(const TaskList& tasks) {
if (tasks.empty()) { std::println("(没有任务)"); return; }
for (std::size_t i = 0; i < tasks.size(); ++i) {
const auto& t = tasks[i];
std::println("{} [{}{}] [P{}] {}",
i + 1, t.done ? "✓" : " ", t.done ? " ]" : " ",
t.priority, t.title);
}
}
int main() {
const std::string file = "tasks.txt";
auto tasks = load(file).value_or(TaskList{});
std::string cmd;
while (true) {
std::println("\n命令:add 标题 | done 编号 | del 编号 | list | save | quit");
std::print("> ");
std::getline(std::cin, cmd);
if (cmd == "quit") { save(tasks, file); break; }
if (cmd == "list") { show(tasks); }
else if (cmd == "save") { save(tasks, file); }
else if (cmd.rfind("add ", 0) == 0) {
tasks.push_back({cmd.substr(4), 1, false});
}
else if (cmd.rfind("done ", 0) == 0) {
int i = std::stoi(cmd.substr(5)) - 1;
if (i >= 0 && i < (int)tasks.size()) tasks[i].done = true;
}
else if (cmd.rfind("del ", 0) == 0) {
int i = std::stoi(cmd.substr(4)) - 1;
if (i >= 0 && i < (int)tasks.size())
tasks.erase(tasks.begin() + i);
}
else std::println("看不懂,试试 add 买牛奶");
}
std::println("再见!");
}
功能:埃氏筛求质数、分解质因数、判断素数。 知识点:vector、算法、函数、模板、constexpr。
#include <print>
#include <vector>
#include <cstdint>
std::vector<std::int64_t> sieve_prime_factors(std::int64_t n) {
std::vector<std::int64_t> factors;
for (std::int64_t p = 2; p * p <= n; ++p) {
while (n % p == 0) { factors.push_back(p); n /= p; }
}
if (n > 1) factors.push_back(n);
return factors;
}
std::vector<int> primes_below(int limit) { // 埃氏筛
std::vector<bool> composite(limit + 1, false);
std::vector<int> primes;
for (int i = 2; i <= limit; ++i) {
if (!composite[i]) {
primes.push_back(i);
for (std::int64_t j = (std::int64_t)i * i; j <= limit; j += i)
composite[j] = true;
}
}
return primes;
}
template <std::integral T>
constexpr bool is_prime(T n) {
if (n < 2) return false;
for (T i = 2; i * i <= n; ++i)
if (n % i == 0) return false;
return true;
}
int main() {
constexpr bool p = is_prime(97); // 编译期就算好了
static_assert(p == true);
std::println("100 以内的质数有 {} 个", primes_below(100).size());
for (std::int64_t n : {100, 360, 97, 123456789}) {
auto f = sieve_prime_factors(n);
std::println("{} = {}", n,
std::format("{}", f) ); // 直接打印 vector
}
}
运行需要 #include <print> 和 <concepts>(std::format 支持直接格式化 vector)。
可选进阶:新版 libc++ 支持 views::transform + join_with,打印成 "2 * 2 * 5 * 5" 这种形式;你的环境版本旧,用 format 打 vector 最简单。
学完本书,你已经掌握现代 C++ 的主体。继续前进的路标:
std::async、原子操作、无锁编程(进阶)
包管理(vcpkg/conan)、CI
数据库引擎、渲染器——以作品代练习
推荐开源项目阅读顺序(GitHub 上搜):
C++ 学的是"控制"与"责任"的平衡。掌握现代 C++(17+), 你可以写出和 Python 一样清晰、和 C 一样快的程序。 把这本书当成工具书:概念忘了就翻对应章节, 关键是动手——把每个练习敲出来、改一改、跑起来。 你已经在正确的道路上了,加油。