代码仓库shanchuann/CPP-Learninng
1 2 #include <string> #include <string.h>
#include<string.h>:是C 语言标准库 的头文件(C 标准),主要用于处理C 风格字符串 (即以空字符'\0'结尾的字符数组,如char str[] = "hello")。它是 C 语言中字符串操作的基础头文件,C++ 为了兼容 C 语言,也支持包含该头文件。
#include<string>:是C++ 标准库 的头文件(C++ 标准),专门用于支持 C++ 中的 **std::string类 **(一种封装了字符串功能的 C++ 类)。它是 C++ 面向对象思想下对字符串的封装,提供了更安全、便捷的字符串操作方式。
1 2 3 4 5 6 int main () { string s1 = "Hello" ; string s2 = "World" ; string s3 = s1 + " " + s2; cout << s3 << endl; }
在 C++ 中,std::string 是标准库提供的字符串类,它封装了字符串的存储、管理和操作,彻底解决了 C 语言中 char*(C 风格字符串)手动管理内存、易出现缓冲区溢出的痛点。无论是日常开发还是算法实现,std::string 都是处理字符串的首选工具,掌握它能极大提升代码的安全性和开发效率。
std::string 是什么 std::string 本质是 C++ 标准库(<string> 头文件)中定义的模板类 (实际是 basic_string<char> 的别名),核心作用是:
自动管理字符串内存:无需手动分配/释放空间,避免内存泄漏和越界;
封装常用字符串操作:提供拼接、查找、截取、替换等现成接口,无需重复实现;
兼容 C 风格字符串:支持与 char* 互相转换,兼顾旧代码场景。
定义与初始化
初始化方式
代码示例
说明
默认初始化
std::string s;
创建空字符串,长度为 0
直接赋值字符串
std::string s = "hello";
用 C 风格字符串初始化
拷贝初始化
std::string s1 = s2;
用另一个 string 对象拷贝创建
截取子串初始化
std::string s = "abcdef", s1(s, 2, 3);
从 s 的索引 2 开始,取 3 个字符(结果为 “cde”)
重复字符初始化
std::string s(5, 'a');
创建 5 个 ‘a’ 组成的字符串(”aaaaa”)
常用操作 获取长度与判空
size() / length():返回字符串长度(两者功能完全一致,推荐用 size() 适配容器习惯);
empty():判断字符串是否为空(比 size() == 0 更高效,推荐使用)。
1 2 3 std::string s = "C++ string" ; cout << s.size (); cout << s.empty ();
拼接、赋值与清空
append(const string& str):在当前字符串后拼接另一个字符串(也可用 += 简化);
operator=:直接赋值新字符串(覆盖原有内容);
clear():清空字符串(长度变为 0,不释放内存,仅标记为空);
push_back(char c):在末尾添加单个字符。
1 2 3 4 std::string s = "Hello" ; s.append (" World" ); s += "!" ; s.clear ();
定位字符/子串
find(const string& str, size_t pos = 0):从索引 pos 开始查找子串 str,返回首次出现的起始索引;若未找到,返回 std::string::npos(一个极大值,代表“无此位置”);
replace(size_t pos, size_t len, const string& str):从索引 pos 开始,删除 len 个字符,再插入 str。
1 2 3 4 5 6 7 8 std::string s = "I love C++, C++ is easy!" ; size_t pos = s.find ("C++" ); cout << pos; s.replace (pos, 3 , "C plus plus" ); cout << s;
提取部分内容
substr(size_t pos = 0, size_t len = npos):从索引 pos 开始,截取 len 个字符;若 len 不指定,默认截取到字符串末尾。
1 2 3 std::string s = "abcdefgh" ; std::string sub1 = s.substr (2 ); std::string sub2 = s.substr (2 , 3 );
简化代码的“语法糖” std::string 重载了多个常用操作符,让字符串操作像“用变量”一样简单:
operator+:拼接两个字符串(s1 + s2,返回新字符串,不修改原对象);
operator== / != / < / >:比较两个字符串(按 ASCII 码顺序,区分大小写);
operator[]:通过索引访问单个字符(无越界检查 ,越界会导致未定义行为);
at(size_t pos):通过索引访问字符(有越界检查 ,越界会抛出 out_of_range 异常,更安全)。
1 2 3 4 std::string s1 = "apple" , s2 = "banana" ; cout << (s1 < s2); cout << s1[1 ]; cout << s1. at (10 );
与 C 风格字符串的转换 实际开发中,有时需要将 std::string 与 C 风格的 char* 互相转换(如调用 C 语言接口),核心接口如下:
c_str():返回 const char* 类型的 C 风格字符串(末尾含 '\0',只读,不能修改);
data():C++17 后与 c_str() 功能一致,返回 const char*(早期版本不含 '\0',需注意兼容性);
从 char* 转 std::string:直接用 char* 初始化 std::string 即可(自动拷贝内容)。
1 2 3 4 5 6 7 const char * c_str = "Hello C" ;std::string s = c_str; const char * new_c_str = s.c_str ();cout << new_c_str;
对比 C 风格字符串 相比 C 语言的 char*,std::string 的优势非常明显,也是它成为主流的原因:
对比维度
C 风格字符串(char*)
C++ std::string
内存管理
手动分配(malloc)、释放(free),易泄漏
自动管理,无需手动操作
安全性
无越界检查,易出现缓冲区溢出
提供 at() 越界检查,empty() 判空
操作便捷性
需调用 strlen/strcpy 等函数
重载操作符(+、=、==),成员函数直观
功能扩展性
无默认拼接、查找等功能,需自定义
内置拼接、查找、替换等全套接口