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

C++中string常用方法总结

📝前言:
STL(standard template libaray-标准模板库):是C++标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架。今天就让我们先学习STL中的重要容器之一——string(文中表粗为重要用法)

🎬个人简介:努力学习ing
📋个人专栏:C++学习笔记
🎀CSDN主页 愚润求学
🌄其他专栏:C语言入门基础,python入门基础,python刷题专栏


文章目录

  • 一,了解STL
  • 二,string常用接口
    • 1. 构造函数
    • 2. 赋值操作
    • 3. 元素访问及遍历
    • 4. 大小和容量操作
    • 5. 修改操作
    • 6. 子字符串操作
    • 7. 查找操作
    • 8. 比较操作
    • 10. C 风格字符串转换
    • 11. getline

一,了解STL

STL 最初由 Alexander Stepanov 等人开发,后被纳入 C++ 标准。STL 有标准规范,但是,不同公司为了提高性能,或者其他原因,在实现 STL 时,在底层数据结构和算法的选择上可能会有差异。比如,Visual C++ 编译器中自带的 STL 实现和GCC 编译器中的 STL 实现就有所差异。

  • STL主要由以下六个部分组成:
    在这里插入图片描述
    在学习STL的时候,更多是一个探索过程,我们要多查文档了解用法,在实践和练习中学习。https://legacy.cplusplus.com/reference/这个文档按头文件整理,虽然不是官方的,但是对初学者较为友好。

二,string常用接口

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

	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 的字符串。

示例:

    std::string s1; // 空的string类对象// 使用 C 风格字符串初始化std::string s2("Hello, World!");// 使用拷贝构造函数,用 s2 初始化 s3std::string s3(s2);// 创建一个包含 5 个字符 'A' 的字符串std::string s4(5, 'A');

2. 赋值操作

  • string& operator=(const string& str): 赋值操作符。
    std::string str1 = "Initial value"; // 这是拷贝构造初始化std::string str2;// 使用赋值操作符 = 将 str1 的内容赋给 str2str2 = str1;

3. 元素访问及遍历

  • char& operator[](size_t pos): 访问指定位置的字符(不检查边界)。就和使用数组下标一样。
    std::string str = "Hello, World!";// 使用 operator[] 访问指定位置的字符(不检查边界)// 修改指定位置的字符str[0] = 'h';

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

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

利用迭代器访问:

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;
}

输出:

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

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

    // 使用范围 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(): 清空字符串。(但是开的空间不清)
#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

示例:

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 个字符为 strstd::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 个字符组成的子字符串。

示例:

    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
  • find_first_of :有多个函数重载,用于在字符串中查找指定字符集合中任意一个字符首次出现的位置
  • find_last_of:与find_first_of类似,从字符串的末尾开始向前查找,用于在字符串中查找指定字符集合中任意一个字符最后一次出现的位置。

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

示例:

#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 开始查找子字符串 strsize_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 开始反向查找子字符串 strsize_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;
}

运行结果:
在这里插入图片描述

find_frst_of示例:

    std::string str = "Hello, World!";// 查找字符串中任意一个数字字符首次出现的位置std::string digits = "0123456789";size_t found1 = str.find_first_of(digits);// 从位置 5 开始查找字符串中任意一个标点符号首次出现的位置std::string punctuations = ".,!?;:";size_t found2 = str.find_first_of(punctuations, 5);// 查找字符串中字符 'o' 首次出现的位置size_t found3 = str.find_first_of('o');

find_last_of示例:

    std::string str = "Hello, World!";// 查找字符串中任意一个字母字符最后一次出现的位置std::string letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";size_t found1 = str.find_last_of(letters);// 从位置 8 开始向前查找字符串中任意一个标点符号最后一次出现的位置std::string punctuations = ".,!?;:";size_t found2 = str.find_last_of(punctuations, 8);// 查找字符串中字符 'l' 最后一次出现的位置size_t found3 = str.find_last_of('l');

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 方法提供了更多的重载形式,支持用索引值和长度定位子串来进行比较,功能灵活

#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 风格字符串的指针。

示例:

#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。当遇到该分隔符时,读取停止(不会读取分隔符)。

示例:

#include <iostream>
#include <string>int main() {std::string line;std::cout << "请输入一行文本:";// 使用默认分隔符(换行符)读取一行std::getline(std::cin, line);std::cout << "你输入的文本是:" << line << std::endl;return 0;
}

🌈我的分享也就到此结束啦🌈
要是我的分享也能对你的学习起到帮助,那简直是太酷啦!
若有不足,还请大家多多指正,我们一起学习交流!
📢公主,王子:点赞👍→收藏⭐→关注🔍
感谢大家的观看和支持!祝大家都能得偿所愿,天天开心!!!


http://www.mrgr.cn/news/94540.html

相关文章:

  • 6.PE文件新增节
  • 【算法】动态规划
  • 扩散模型:AIGC领域的核心引擎,解锁图像生成新维度
  • 【2025最新】深度学习框架PyTorch——从入门到精通(1)下载与安装
  • spring 创建单例 Bean 源码分析
  • k8s集群-kubeadm init
  • 压敏电阻结构特点及选型指南
  • 【图论】并查集的学习和使用
  • 卫语句优化多层if else嵌套
  • 计算机视觉cv2入门之边缘检测
  • Python Matplotlib面试题精选及参考答案
  • Python精进系列:隐藏能力之魔术方法
  • 315周六复盘(118)本周回顾
  • 入门基础项目-前端Vue_02
  • UE4-UE5虚幻引擎,前置学习一--Console日志输出经常崩溃,有什么好的解决办法
  • MySQL开发陷阱与最佳实践:第1章:MySQL开发基础概述-1.2 MySQL开发环境搭建
  • 链表·简单归并
  • 【技术支持】记一次mac电脑换行符差异问题
  • 精通游戏测试笔记(持续更新)
  • 【云原生技术】容器技术的发展史