C++中std::string和std::string_view使用详解和示例

std::string

一、std::string 简介

std::string 是 C++ 标准库提供的字符串类,封装了动态管理的字符数组,功能比传统的 C 风格字符串(char*)更强大、安全、易用。

属于头文件:<string>

所在命名空间:std

主要优点:

  • 自动内存管理(不需要手动分配/释放)
  • 提供丰富的字符串操作函数(拼接、查找、替换等)
  • 与流(如 cin / cout)兼容性好
  • 支持下标访问与迭代器

二、基本用法示例

cpp 复制代码
#include <iostream>
#include <string>

int main() {
    std::string s1 = "Hello";
    std::string s2 = "World";
    std::string s3 = s1 + " " + s2; // 拼接

    std::cout << s3 << std::endl; // 输出:Hello World

    std::cout << "字符串长度:" << s3.length() << std::endl;
    std::cout << "第二个字符:" << s3[1] << std::endl;

    return 0;
}

三、常用成员函数汇总(+ 示例)

方法 说明 示例
.size() / .length() 获取字符串长度 s.length()
.empty() 判断是否为空 if (s.empty())
.at(i) 安全访问第 i 个字符(带边界检查) s.at(0)
.append(str) 追加字符串 s.append(" World")
.insert(pos, str) 插入子串 s.insert(5, ",")
.erase(pos, len) 删除部分内容 s.erase(5, 1)
.replace(pos, len, str) 替换部分内容 s.replace(0, 5, "Hi")
.substr(pos, len) 截取子串 s.substr(0, 5)
.find(str) 查找子串位置 s.find("llo")
.rfind(str) 从后向前查找 s.rfind("o")
.compare(str) 字符串比较(返回值类似 strcmp) s.compare("abc")
.c_str() 转为 C 风格字符串(返回 const char* printf("%s", s.c_str())

四、遍历方式

cpp 复制代码
std::string s = "Hello";

// 方式1:下标访问
for (size_t i = 0; i < s.size(); ++i)
    std::cout << s[i] << ' ';

// 方式2:范围 for 循环
for (char c : s)
    std::cout << c << ' ';

// 方式3:迭代器
for (auto it = s.begin(); it != s.end(); ++it)
    std::cout << *it << ' ';

五、与 C 字符串的互转

cpp 复制代码
std::string cppStr = "hello";
const char* cStr = cppStr.c_str();  // C++ -> C

std::string newStr(cStr);           // C -> C++

六、注意事项

  • string::at() 带边界检查,安全但略慢;[] 不检查越界。
  • std::getline(cin, s) 配合时注意清除输入缓冲区。
  • 不要对 .c_str() 返回的指针进行修改,它是只读的。

七、实战小示例:字符串反转

cpp 复制代码
#include <iostream>
#include <string>
#include <algorithm>

int main() {
    std::string s = "abcdefg";
    std::reverse(s.begin(), s.end());
    std::cout << s << std::endl;  // 输出:gfedcba
}

std::string_view

一、std::string_view:轻量字符串视图(C++17 起)

简介

std::string_view 是一个非拥有型的只读字符串引用,不分配内存、不复制数据,适用于传参和高效处理子串。

关键特性

  • 快速,无拷贝(零开销)
  • 支持与 std::string 类似的操作(如 substr, find
  • 生命周期由原始字符串控制,不能跨作用域使用

示例:

cpp 复制代码
#include <iostream>
#include <string>
#include <string_view>

void greet(std::string_view name) {
    std::cout << "Hello, " << name << std::endl;
}

int main() {
    std::string full = "Alice Wonderland";
    std::string_view sv = full.substr(0, 5);  // "Alice"
    greet(sv);
}

用于高性能接口设计,可避免大量 string 拷贝。


二、性能优化技巧(std::string)

1. 减少重复构造

避免 string 频繁复制、构造,尽量使用引用或 std::string_view

cpp 复制代码
void process(const std::string& s);  // 优于传值

2. 预分配容量 .reserve()

避免频繁扩容导致的内存复制:

cpp 复制代码
std::string data;
data.reserve(1024);  // 提前分配空间,避免多次 realloc

3. 避免 += 拼接过多次(会触发多次 reallocation)

可改用:

cpp 复制代码
std::ostringstream oss;
oss << "Name: " << name << ", Age: " << age;
std::string result = oss.str();

三、Unicode / UTF-8 字符处理(中文、Emoji等)

C++ std::string 本身对字符集不做解释,只是按字节存储。

示例:
cpp 复制代码
std::string str = "你好";  // 实际为 6 个字节,不是 2 个字符
std::cout << str.length();  // 输出:6

推荐处理 UTF-8 的库:

特点
utf8cpp 轻量、纯头文件库
ICU(Intl Components for Unicode) 功能强大,适用于多语言、排序等
C++20 char8_t / std::u8string 新的 UTF-8 字符类型(现代C++,但库支持有限)

使用 utf8cpp 示例(读取 UTF-8 字符):

cpp 复制代码
#include <utf8.h>
std::string s = "你好世界";
auto it = s.begin();
while (it != s.end()) {
    uint32_t cp = utf8::next(it, s.end());
    std::cout << std::hex << cp << " ";
}

四、常见误区与调试建议

1. c_str() 返回的是 const char*,不能修改其内容

cpp 复制代码
char* p = s.c_str();  // 编译器可能允许,但是 UB(未定义行为)

2. 不要返回局部 string_view

cpp 复制代码
std::string_view get_name() {
    std::string tmp = "Tom";
    return tmp;  // ❌ tmp 销毁后 string_view 悬空
}

调试建议

  • 使用 .data() + .size() 查看原始字节内容
  • .substr() 替代手动字符切片(更安全)
  • 使用 std::u32string 处理 Unicode(每字符固定宽度)

总结:适用场景对比

功能需求 建议使用
动态字符串、读写操作 std::string
只读子串、传参 std::string_view
跨平台 Unicode 处理 utf8cppICU
UTF-16 / UTF-32 字符 std::u16string, std::u32string

相关推荐
BothSavage9 小时前
Trae远程开发中DeepSeek自定义模型4054错误的排查与修复
算法
小林ixn10 小时前
从暴力到KMP:一道题彻底搞懂字符串匹配的前世今生
算法
烬羽11 小时前
字符串算法入门:从反转字符串到回文判断,面试不再慌
算法·面试
郝学胜_神的一滴11 小时前
CMake 034:生成器表达式:解耦构建时序、精简分支逻辑的终极利器
c++·cmake
先吃饱再说1 天前
判断回文字符串,从一行代码到双指针优化
算法
见过夏天1 天前
C++ 基础入门完全指南
c++
黄敬峰1 天前
深入理解算法核心:从递归思想、数组扁平化到快速排序
算法
得物技术1 天前
从狂野代码到按目标生产:得物推荐 AI Harness 的工程化实践|AICon 演讲整理
人工智能·算法·架构
AI小老六1 天前
SkillOpt 架构拆解:把 Skill 文本当参数,用执行轨迹训练 Agent
后端·算法·ai编程