跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
C++

C++ std::string 核心用法与底层原理

C++ std::string 是标准库提供的字符串类,封装了 char* 并管理内存。支持多种初始化方式、容量控制及元素访问。提供查找、子串、类型转换等常用操作。C++17 引入 string_view 避免拷贝开销,C++20 新增 starts_with 等接口。底层涉及 SSO 优化短字符串存储,COW 机制已废弃。最佳实践包括参数传递选择、reserve 预分配及安全性注意事项。

kaikai发布于 2026/3/16更新于 2026/10/991 浏览

std::string 是 C++ Standard Library 提供的标准类之一,也是 C++ 开发中最常用的类之一。它本质上是对 C 风格字符串(char*)的封装,提供了自动内存管理和丰富的操作接口。

核心概念

std::string 位于 <string> 头文件中,本质上是对 std::basic_string<char> 的特化版本。

  • 头文件:#include <string>
  • 命名空间:std
  • 特点:动态管理内存,自动处理扩容,兼容 C 风格字符串。

初始化与构造

#include <string>
#include <vector>

std::string s1; // 默认构造,空字符串 ""
std::string s2 = "Hello, World"; // 拷贝初始化
std::string s3("Hello, World"); // 直接初始化
std::string s4(5, 'A'); // 生成 "AAAAA"
std::string s5(s2); // 拷贝构造
std::string s6(s2, 1, 3); // 子串构造:从索引 1 开始取 3 个字符 -> "ell"
// C++11 及以后
std::string s7 = {'H', 'i'}; // 列表初始化

容量与属性

了解容量对于优化性能至关重要,特别是避免不必要的内存重分配。

函数说明备注
size() / length()返回字符数量两者完全等价,一般用 size()
empty()判断是否为空推荐使用,比 size() == 0 语义更清晰
capacity()当前分配的内存容量通常 >=size()
reserve(n)预分配 n 字节内存避免 append 时的多次内存重分配
shrink_to_fit()释放多余内存(C++11)让 capacity 接近 size

元素访问与遍历

访问单个字符
  • operator[]:s[i]。不检查越界,效率高,但越界会导致未定义行为。
  • at():s.at(i)。检查越界,越界会抛出 std::out_of_range 异常。
  • front() / back():访问首尾字符。
C 风格字符串
  • c_str():返回 const char*,以 NULL 结尾。主要用于兼容旧式 C 接口(如 printf)。
  • data():C++11 前不保证 NULL 结尾,C++11 后与 c_str() 基本一致。
遍历
std::string s = "Hello, World";

// 1. 基于下标
for (size_t i = 0; i < s.size(); ++i) {
    /* ... */
}

// 2. 基于迭代器
for (auto it = s.begin(); it != s.end(); ++it) {
    /* ... */
}

// 3. 基于范围 for 循环(C++11,推荐)
// 值拷贝
for (char c : s) {
    /* ... */
}
// 引用修改
for (char& c : s) {
    c = toupper(c);
}

修改与操作

操作函数示例
追加+=、append()、push_back()s += " World"
插入insert(pos, str)s.insert(0, "Hi ")
删除erase(pos, len), pop_back()s.erase(0, 3)
替换replace(pos, len, str)s.replace(6, 5, "C++")
清空clear()把 size 设置为 0,capacity 通常不变
截断/扩充resize(n)改变 size,多出的补默认值

查找与子串

所有查找函数如果未找到,都会返回常量 std::string::npos(通常是 -1 的无符号形式,即最大的 size_t())。

std::string s = "filename.txt";

// 1. 查找
size_t pos = s.find(".");
if (pos != std::string::npos) {
    // 找到了
}

// 2. 反向查找 rfind(找最后一个出现的位置)
size_t last_dot = s.rfind(".");

// 3. 查找集合 find_first_of / find_first_not_of
// 查找第一个出现的元音字母
size_t v_pos = s.find_first_of("aeiou");

// 4. 获取子串 substr
// 参数:substr(开始位置,长度)
std::string name = s.substr(0, pos); // "filename"
std::string ext = s.substr(pos + 1); // "txt"(省略长度则取到末尾)

类型转换

需要包含头文件 <string>。

数值转字符串 std::to_string(value)
std::string s = std::to_string(3.14); // "3.140000"
字符串转数值
  • std::stoi(s):int
  • std::stol(s):long
  • std::stod(s):double
  • 注意:这些函数会处理前导空格,但遇到非法字符会抛异常

现代化特性

C++17:std::string_view

std::string 是'拥有者',其拷贝开销大。std::string_view 只是一个'观察者'(包含指针和长度),零拷贝。

函数参数尽量使用 std::string_view 代替 const std::string&,特别是当你只需要读取字符串内容时。

// 避免了临时 std::string 对象的构造和内存分配
void print_prefix(std::string_view sv) {
    if (sv.substr(0, 3) == "Pre") {
        // substr 也是 O(1) 操作
        // ...
    }
}
C++20

填补了长期以来 C++ std::string 缺少高频接口的遗憾:

  • s.starts_with("prefix"):判断前缀
  • s.ends_with("suffix"):判断后缀
  • s.contains("sub"):判断包含

底层原理

SSO(Small String Optimization)

原理:为了避免短字符串频繁的堆内存分配(Heap Allocation),std::string 内部通常有一个小的栈缓冲区(通常 15 或 22 字节,取决于编译器实现)。

效果:

  • 如果字符串很短(例如:"Hello"),直接存放在栈上对象内部,无 malloc,速度极快。
  • 如果字符串变长,才会在堆上分配内存,指针指向堆。
COW(Copy-On-Write)

在 C++11 之后已被废弃。现在的标准规定 std::string 不允许使用 COW。这意味着 std::string a = b; 一定会发生深拷贝(除非使用 std::move)。

最佳实践

参数传递
  • 只读不拥有:C++17 前用 const std::string&,C++17 后优先用 std::string_view。
  • 需要修改:用 std::string&。
  • 需要拥有权(Sink):可以直接传值 std::string 并配合 std::move。
性能优化
  • 在循环中追加字符串前,先用 reserve() 预留空间(写在循环之前)。
  • 尽量避免在循环内部频繁构造 std::string。
  • 换行符优先用 \n 而不是 std::endl(除非你需要立即刷新缓冲区)。
安全性
  • 永远不要对 c_str() 返回的指针进行 delete 操作。
  • 当 string 对象被修改或销毁后,之前获取的 iterators、references 和 pointers(如 c_str() 的结果)可能会失效。

目录

  1. 核心概念
  2. 初始化与构造
  3. 容量与属性
  4. 元素访问与遍历
  5. 访问单个字符
  6. C 风格字符串
  7. 遍历
  8. 修改与操作
  9. 查找与子串
  10. 类型转换
  11. 数值转字符串 std::to_string(value)
  12. 字符串转数值
  13. 现代化特性
  14. C++17:std::string_view
  15. C++20
  16. 底层原理
  17. SSO(Small String Optimization)
  18. COW(Copy-On-Write)
  19. 最佳实践
  20. 参数传递
  21. 性能优化
  22. 安全性

更多推荐文章

查看全部
  • 排序算法指南:归并排序非递归实现
  • Linux 文件 IO 缓冲区机制深度解析
  • OpenClaw 接入飞书机器人与 Ollama 本地大模型实战
  • 网络安全入门与进阶学习路线指南
  • 系统高可用架构中的服务降级策略与实践
  • SeeDream 4.0 AI 修图与生成教程
  • YOLO12 应用于无人机倾斜摄影密集楼宇窗户识别
  • OpenClaw + GitHub Copilot GPT-5.4 技术修复指南
  • Android 面试核心知识点与项目经验总结
  • ERNIE-4.5-0.3B 轻量级模型部署指南与能力测评
  • DeepSeek 与 Neo4j 构建企业级 GraphRAG 技术解析
  • WorkBuddy 接入 QQ 机器人配置指南
  • IDM 激活脚本技术原理与使用注意事项
  • LeetCode 3661 可以被机器人摧毁的最大墙壁数目解法分析
  • 学术论文查重与 AIGC 检测工具功能实测与分析
  • 大模型训练核心算法:损失函数详解
  • 无人机开发自学指南:从基础理论到项目实践
  • IDEA 配置 Tomcat 服务器详细教程
  • 基于红黑树封装 C++ map/set:源码级实现与核心逻辑解析
  • Diffusion Transformer (DiT):用 ViT 替代 U-Net,赋能视频生成与机器人动作预测

相关免费在线工具

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online

  • JSON美化和格式化

    将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online