当前位置: 首页 > news >正文

C++中string常用方法总结

  • STL主要由以下六个部分组成:

在学习STL的时候,更多是一个探索过程,我们要多查文档了解用法,在实践和练习中学习。https://legacy.cplusplus.com/reference/这个文档按头文件整理,虽然不是官方的,但是对初学者较为友好。

二,string常用接口

在 C++ 里,std::string是标准库中的类,它处于std命名空间中。 首先介绍一下string和C风格字符串的区别:

代码语言:javascript

AI代码解释

string s1("hello world"); char s2[] = "hello world";

对于上面两个字符串在内存中的存储,s1不带\0s2\0

所以对于C风格的字符串,我们无法直接使用string的方法,对于string类型的字符串,我们要使用C风格字符串的方法需要通过c_str()转换成C风格的字符串,因为C风格的字符串操作大多是需要使用\0的。

1. 构造函数
  • string(): 默认构造函数,创建一个空字符串。
  • string(const char* s): 用 C 风格字符串初始化。
  • string(const string& str): 拷贝构造函数。
  • string(size_t n, char c): 创建一个包含n个字符c的字符串。

示例:

代码语言:javascript

AI代码解释

std::string s1; // 空的string类对象 // 使用 C 风格字符串初始化 std::string s2("Hello, World!"); // 使用拷贝构造函数,用 s2 初始化 s3 std::string s3(s2); // 创建一个包含 5 个字符 'A' 的字符串 std::string s4(5, 'A');
2. 赋值操作
  • string& operator=(const string& str): 赋值操作符。

代码语言:javascript

AI代码解释

std::string str1 = "Initial value"; // 这是拷贝构造初始化 std::string str2; // 使用赋值操作符 = 将 str1 的内容赋给 str2 str2 = str1;
3. 元素访问及遍历
  • char& operator[](size_t pos): 访问指定位置的字符(不检查边界)。就和使用数组下标一样。

代码语言:javascript

AI代码解释

std::string str = "Hello, World!"; // 使用 operator[] 访问指定位置的字符(不检查边界) // 修改指定位置的字符 str[0] = 'h';

==迭代器==是学习容器非常重要的一个概念,迭代器类似指针,也可以加减来移动,但是不能大小比较,且不同类型的迭代器不能比较(如iteratorreverse_iterator类型不能比较)

  • iterator begin(): 返回指向字符串开头的迭代器。
  • iterator end(): 返回指向字符串末尾的迭代器。
  • reverse_iterator rbegin(): 返回指向字符串末尾的反向迭代器。
  • reverse_iterator rend(): 返回指向字符串开头的反向迭代器。

利用迭代器访问:

代码语言:javascript

AI代码解释

int main() { std::string str = "Hello, World!"; // 使用 begin() 和 end() 正向遍历字符串 std::cout << "正向遍历字符串: "; for (std::string::iterator it = str.begin(); it != str.end(); ++it) { std::cout << *it; } std::cout << std::endl; // 使用 rbegin() 和 rend() 反向遍历字符串 std::cout << "反向遍历字符串: "; for (std::string::reverse_iterator rit = str.rbegin(); rit != str.rend(); ++rit) { std::cout << *rit; } std::cout << std::endl; return 0; }

输出:

代码语言:javascript

AI代码解释

正向遍历字符串: Hello, World! 反向遍历字符串: !dlroW ,olleH

auto用于自动推到类型,常用在替换较长的代码名称。 注意:auto声明的变量必须有初始值,因为编译器需要根据初始值来推导类型。且auto不能用在函数参数 利用auto和范围for访问:

代码语言:javascript

AI代码解释

// 使用范围 for 和 auto 访问 for (auto ch : str) { std::cout << ch; } return 0; }
4. 大小和容量操作
  • size_t size() const: 返回字符串的长度。
  • size_t length() const: 与size()相同,返回字符串的长度。
  • bool empty() const: 判断字符串是否为空。
  • void resize(size_t n): 调整字符串的大小。
  • size_t capacity() const: 返回当前分配的存储空间大小。
  • void reserve(size_t n): 预留存储空间。
  • void clear(): 清空字符串。(但是开的空间不清)

代码语言:javascript

AI代码解释

#include <iostream> #include <string> int main() { // 定义一个字符串对象并初始化为 "Hello" std::string str = "Hello"; // 使用 size() 方法返回字符串的长度 // 这里输出字符串使用 size() 方法得到的长度 std::cout << "使用 size() 方法得到的字符串长度: " << str.size() << std::endl; // 使用 length() 方法返回字符串的长度 // length() 和 size() 功能一样,这里输出使用 length() 方法得到的长度 std::cout << "使用 length() 方法得到的字符串长度: " << str.length() << std::endl; // 使用 empty() 方法判断字符串是否为空 // 根据 empty() 的返回结果输出字符串是否为空的信息 std::cout << "字符串是否为空? " << (str.empty() ? "是" : "否") << std::endl; // 使用 resize() 方法调整字符串的大小 // 将字符串大小调整为 10,如果新长度大于原长度,用 '!' 填充,如果新长度小于原长度,则截断 str.resize(10, '!'); // 输出调整大小后的字符串 std::cout << "调整大小为 10 并用 '!' 填充后的字符串: " << str << std::endl; // 输出调整大小后字符串的新长度 std::cout << "调整大小后的新长度: " << str.size() << std::endl; // 使用 capacity() 方法返回当前为字符串分配的存储空间大小 std::cout << "当前字符串分配的存储空间大小: " << str.capacity() << std::endl; // 使用 reserve() 方法预留存储空间 // 预留至少能容纳 20 个字符的存储空间 str.reserve(20); // 输出预留存储空间后的容量 std::cout << "预留 20 个字符存储空间后的容量: " << str.capacity() << std::endl; // 使用 clear() 方法清空字符串 str.clear(); // 再次使用 empty() 方法判断字符串是否为空并输出结果 std::cout << "清空字符串后是否为空? " << (str.empty() ? "是" : "否") << std::endl; return 0; }

运行结果:

说明:为什么预留reserve(20)但是开的capacity31? 首先,先了解一下string的自动扩容: 当向string中添加字符,使得字符数量超过其当前分配的容量capacity时,string会自动进行扩容操作。但是,不同的标准库实现可能采用不同的扩容策略,但常见的做法是按照一定的倍数进行扩容。例如,当需要扩容时,可能会将容量扩大为原来的2 倍,这样可以减少频繁扩容带来的性能开销。 所以当我们reserve(20)的时候,编译器会根据自己的标准进行扩容,确保开的空间是>=20的。 对于reserve(n),如果n比目前的字符串小,就不会执行,但是如果比capacity小,比字符串大则可能执行,由编译器决定.

5. 修改操作
  • string& append(const string& str): 在字符串末尾追加字符串。
  • string& operator+=(const string& str): 追加字符串。
  • void push_back(char c): 在字符串末尾追加一个字符。
  • string& insert(size_t pos, const string& str): 在指定位置插入字符串。
  • string& erase(size_t pos = 0, size_t len = npos): 删除从pos开始的len个字符。
  • string& replace(size_t pos, size_t len, const string& str): 替换从pos开始的len个字符为str

示例:

代码语言:javascript

AI代码解释

int main() { std::string str = "Hello"; // 使用 append(const string& str) 在字符串末尾追加字符串 std::string appendStr = ", World"; str.append(appendStr); std::cout << "使用 append 追加后: " << str << std::endl; // 使用 operator+=(const string& str) 追加字符串 std::string anotherAppend = "!"; str += anotherAppend; std::cout << "使用 += 追加后: " << str << std::endl; // 使用 push_back(char c) 在字符串末尾追加一个字符 str.push_back('?'); std::cout << "使用 push_back 追加字符后: " << str << std::endl; // 使用 insert(size_t pos, const string& str) 在指定位置插入字符串 std::string insertStr = " amazing"; str.insert(5, insertStr); std::cout << "在位置 5 插入字符串后: " << str << std::endl; // 使用 erase(size_t pos = 0, size_t len = npos) 删除从 pos 开始的 len 个字符 str.erase(5, insertStr.length()); std::cout << "删除插入的字符串后: " << str << std::endl; // 使用 replace(size_t pos, size_t len, const string& str) 替换从 pos 开始的 len 个字符为 str std::string replaceStr = "Hi"; str.replace(0, 5, replaceStr); std::cout << "替换前 5 个字符后: " << str << std::endl; return 0; }

运行结果:

6. 子字符串操作
  • string substr(size_t pos = 0, size_t len = npos) const: 返回从pos开始的len个字符组成的子字符串。

示例:

代码语言:javascript

AI代码解释

std::string mainStr = "Hello, Hello, World!"; std::string Sub = mainStr.substr(3, 7); std::cout << Sub << std::endl; // 输出:lo, Hel
7. 查找操作
  • size_t find(const string& str, size_t pos = 0) const: 从pos开始查找子字符串str
  • size_t rfind(const string& str, size_t pos = npos) const: 从pos开始反向查找子字符串str

nposstatic const size_t类型的-1,但是size_t是一种无符号整数类型,所以以补码的形式存储-1就相当于一个很大的数

示例:

代码语言:javascript

AI代码解释

#include <iostream> #include <string> int main() { std::string mainStr = "Hello, Hello, World!"; std::string subStr = "Hello"; // 使用 find(const string& str, size_t pos = 0) 从 pos 开始查找子字符串 str size_t foundPos = mainStr.find(subStr, 0); if (foundPos != std::string::npos) { std::cout << "使用 find 从位置 0 开始查找,首次找到 \"" << subStr << "\" 的位置是: " << foundPos << std::endl; } else { std::cout << "使用 find 从位置 0 开始查找,未找到 \"" << subStr << "\"。" << std::endl; } // 从位置 7 开始查找 foundPos = mainStr.find(subStr, 7); if (foundPos != std::string::npos) { std::cout << "使用 find 从位置 7 开始查找,找到 \"" << subStr << "\" 的位置是: " << foundPos << std::endl; } else { std::cout << "使用 find 从位置 7 开始查找,未找到 \"" << subStr << "\"。" << std::endl; } // 使用 rfind(const string& str, size_t pos = npos) 从 pos 开始反向查找子字符串 str size_t rfoundPos = mainStr.rfind(subStr); if (rfoundPos != std::string::npos) { std::cout << "使用 rfind 反向查找,最后一次找到 \"" << subStr << "\" 的位置是: " << rfoundPos << std::endl; } else { std::cout << "使用 rfind 反向查找,未找到 \"" << subStr << "\"。" << std::endl; } return 0; }

运行结果:

8. 比较操作
  • bool operator==(const string& str) const: 判断两个字符串是否相等。
  • bool operator!=(const string& str) const: 判断两个字符串是否不相等。
  • int compare(const string& str) const: 比较两个字符串

C ++字符串支持常见的比较操作符(>,>=,<,<=,==,!=),甚至支持string与C-string的比较(如 str<”hello”)。 因为会发生隐式类型转换,把C风格的转换成string

示例:compare方法提供了更多的重载形式,支持用索引值和长度定位子串来进行比较,功能灵活

代码语言:javascript

AI代码解释

#include <iostream> #include <string> int main() { std::string str1 = "apple pie"; std::string str2 = "applesauce"; // 比较 str1 从位置 0 开始的 5 个字符和 str2 从位置 0 开始的 5 个字符 int result = str1.compare(0, 5, str2, 0, 5); if (result == 0) { std::cout << "str1 和 str2 的前 5 个字符相等" << std::endl; } return 0; }
10. C 风格字符串转换
  • const char* c_str() const: 返回一个指向 C 风格字符串的指针。

示例:

代码语言:javascript

AI代码解释

#include <iostream> #include <string> #include <cstring> int main() { std::string str1 = "apple"; std::string str2 = "banana"; // 使用 c_str() 转换为 C 风格字符串 const char* cstr1 = str1.c_str(); const char* cstr2 = str2.c_str(); // 使用 C 风格的 strcmp 函数比较两个字符串 int result = strcmp(cstr1, cstr2); if (result < 0) { std::cout << "str1 小于 str2" << std::endl; } else if (result > 0) { std::cout << "str1 大于 str2" << std::endl; } else { std::cout << "str1 等于 str2" << std::endl; } return 0; }
11. getline

getline用于从输入流(标准或文件)中读取一行文本(默认以\n作为分隔符)scanfcin默认是以空白字符(空格、制表符、换行符等)作为分隔来读取数据的。 函数原型:std::istream& getline(std::istream& is, std::string& str, char delim);

  • is:输入流对象,通常是 std::cin 用于从标准输入读取数据。
  • str:用于存储读取到的一行文本的 std::string 对象。
  • delim(可选):分隔符,默认是换行符\n。当遇到该分隔符时,读取停止(不会读取分隔符)。


http://www.jsqmd.com/news/733716/

相关文章:

  • 2026年扬州工厂短视频代运营案例分析 - 速递信息
  • 2026企业AI陪跑推荐:全程陪伴,落地见效 8 - 速递信息
  • 【Laravel AI Security Alert】:2026年Q1已爆发7起Prompt注入+模型越权调用事件,3步修复框架层RCE风险(附CVE-2026-XXXX PoC)
  • Laravel 12模型层AI增强成本封顶设计:3种可插拔式Token配额策略,让每个Eloquent操作自带预算守门员
  • 别再乱配CORS了!Flask-CORS从入门到生产环境安全配置实战(含Nginx反向代理)
  • 基于AI与现金流模拟的自托管个人财务预测机器人开发实践
  • CompressO:如何用这款免费开源工具将视频图片压缩90%以上
  • 为AI代码生成器Cursor配置ESLint与Prettier规则集,实现自动化代码规范检查与格式化
  • 2026连云港黄金回收市场深度解析与靠谱品牌推荐 - 速递信息
  • 【黑马点评日记】异步秒杀:异步线程和阻塞队列以及Lua脚本的相关流程分析
  • R语言偏见检测不可绕过的5个统计陷阱,第3个让OpenAI内部报告延迟发布117天
  • EpiCaR集成学习:动态修正认知不确定性的高效推理方法
  • 【Swoole × LLM 企业级落地白皮书】:3类高敏业务(智能工单、实时投顾、IoT边缘推理)的长连接架构选型决策树与SLA保障方案
  • 多模态模型小型化:挑战与优化策略
  • 2026真心问:重庆本地家教哪家靠谱? - 速递信息
  • 2026唯品会礼品卡回收平台TOP榜:鼎鼎收专业深耕15年,四项五星实力登顶 - 鼎鼎收礼品卡回收
  • 2026年必知!揭秘霞浦美食地道店铺,究竟藏着哪些好用秘诀? - GrowthUME
  • 从纸质到数字:用Audiveris让古老乐谱重获新生的魔法
  • C++11新特性大揭秘:优化性能与简化代码的利器
  • ncmdump终极指南:3分钟解锁网易云音乐加密文件的完整解决方案
  • 1G/2.5G Ethernet PCS/PMA or SGMII IP核(五)
  • packer详解
  • 复杂地带的“生命方舟”:哈尔滨立和气垫船如何破解泥石流与湿地救援困局
  • 如何用Jasminum插件让Zotero中文文献管理效率提升90%
  • 亲测河南GEO厂家的体验居然这么真实? - 速递信息
  • ISO-Bench:AI生成代码性能评估基准测试实践
  • 微信小程序开发笔记
  • DEER-3D:错误驱动增强3D场景理解与编辑
  • EvolVE:LLM与进化算法结合的Verilog自动生成框架
  • 深度学习激活函数选择指南与实战对比