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

相关推荐
REDcker14 分钟前
浏览器端Web程序性能分析与优化实战 DevTools指标与工程清单
开发语言·前端·javascript·vue·ecmascript·php·js
Yzzz-F1 小时前
Problem - 2205D - Codeforces
算法
我命由我123452 小时前
Kotlin 开发 - lateinit 关键字
android·java·开发语言·kotlin·android studio·android-studio·android runtime
智者知已应修善业2 小时前
【51单片机2个按键控制流水灯运行与暂停】2023-9-6
c++·经验分享·笔记·算法·51单片机
Halo_tjn2 小时前
Java Set集合相关知识点
java·开发语言·算法
许彰午2 小时前
我手写了一个 Java 内存数据库(二):B+ 树的插入与分裂
java·开发语言·面试
大飞记Python2 小时前
【2026更新】Python基础学习指南(AI版)——04数据类型
开发语言·人工智能·python
生成论实验室3 小时前
《事件关系阴阳博弈动力学:识势应势之道》第四篇:降U动力学——认知确定度的自驱演化
人工智能·科技·神经网络·算法·架构
AI科技星3 小时前
全域数学·72分册:场计算机卷【乖乖数学】
算法·机器学习·数学建模·数据挖掘·量子计算
Alice-YUE3 小时前
【js高频八股】防抖与节流
开发语言·前端·javascript·笔记·学习·ecmascript