【C++】STL之string 超详解

目录

1.string概述

 2.string使用

1.构造初始化

2.成员函数 

1.迭代器

2.容量操作

 1.size和length   返回字符串长度

2.resize   调整字符串大小

3.capacity   获得字符串容量

4.reserve  调整容量

5.clear  清除

6.empty   判空

3.string插入、追加  、拼接

1.运算符+=  、append

2. push_back

3.insert 

 4.string删除、替换

1.erase

2.pop_back

3. replace

5.字符串操作

1.c_stl

2.data

 3.copy

4.find、rfind

5.find_first_of、find_last_of

6.substr    子串处理

3.string反转(reverse)

4.非成员函数 

1.getline(读取)

2.swap(交换)

3. relational operators(比较)

5.访问遍历 

 6.静态成员常量(npos)


1.string概述

C++的标准库中定义了string类

1. string是表示字符串的字符串类  

2. 该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作

下面是C++的官方网站,若有疑问,可在网站中查询学习 

string - C++ Reference (cplusplus.com)icon-default.png?t=N7T8https://legacy.cplusplus.com/reference/string/string/

 2.string使用

1.构造初始化

#include <iostream>
#include <string>
using namespace std;int main()
{string s1;string s2("hello world");string s3 = s2;string s4(s2);string s5(s2, 1, 6);//用另一个字符串的区间构造cout << s5 << endl;string s6(s2, 1);//用另一个字符串的区间构造cout << s6 << endl;string s7(s2, 1, 100);//用另一个字符串的区间构造cout << s7 << endl;string s8("hello world", 5);//用另一个字符串的区间构造,且只拷贝构造前5个字符cout << s8 << endl;string s9(10, 'x');//单字符构造,构造十个字符cout << s9 << endl;//赋值运算符重载构造s1 = s2;s1 = "world";s1 = 'x';return 0;
}
ello w
ello world
ello world
hello
xxxxxxxxxx

2.成员函数 

1.迭代器

迭代器是一种可以统一使用的遍历方式,迭代器类似于C里面的指针

 

我们可以使用 begin()end() 函数来获取字符串的起始和结束,除了使用迭代器来遍历字符串,我们还可以使用迭代器来进行插入、删除等操作

begin和end是正向迭代器,rbegin和rend是反向迭代器

具体操作请看下面的的 3.访问遍历

2.容量操作

C++的string类提供了许多与字符串容量相关的接口

 1.size和length   返回字符串长度

两者作用相同,都是返回字符串长度,平常推荐用size,其他容器也是用size

string s1("hello world");
cout << s1.size() << endl;
cout << s1.length() << endl;
2.resize   调整字符串大小

 resize调整字符串的大小。该方法可以接收一个参数,用于指定字符串的新大小。如果新大小小于当前大小,则丢弃超出新大小的字符;如果新大小大于当前大小,则在末尾添加空字符或指定的字符。

 string str = "Hello";// 调整字符串为 10 个字符,并在末尾添加 '!'str.resize(10, '!');cout << str << endl;// 调整字符串为 3 个字符,丢弃超出的字符str.resize(3);

resize(size_t n) 与 resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不同的是当字 符个数增多时:resize(n)用0来填充多出的元素空间,resize(size_t n, char c)用字符c来填充多出的 元素空间。注意:resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大 小,如果是将元素个数减少,底层空间总大小不变。 

3.capacity   获得字符串容量

获取字符串的容量

string str = "Hello";
cout << str.capacity() << endl;

需要注意的是,字符串的容量并不一定等于字符串的长度(即字符的个数)。容量表示的是在不重新分配内存的情况下,字符串所能容纳的最大字符数。当字符串的长度超过当前容量时,可能会触发重新分配内存的操作。

4.reserve  调整容量

预留字符串的存储空间,以避免频繁的内存重新分配操作

string str = "Hello";// 预留至少 20 个字符的存储空间
str.reserve(20);// 获取字符串的容量
cout << "Capacity after reserving space: " << str.capacity() << endl;

通过预留存储空间,我们可以避免频繁的内存重新分配操作,从而提高程序的性能和效率。当我们预先知道要存储的字符串较大时,预留足够的存储空间可以减少内存分配的次数,节省时间和资源。需要注意的是,reserve() 方法只会增加字符串的容量,而不会改变字符串的长度。 

5.clear  清除

清空字符串中的内容,使其成为空字符串

string str = "Hello";
// 清空字符串的内容
str.clear();

通过使用clear()方法,我们可以方便地清空字符串的内容,使其变为空字符串。这在需要重复使用同一个字符串对象时非常有用,可以避免反复创建新的字符串对象,节省内存和提高效率。

6.empty   判空

判断字符串是否为空,即字符串的长度是否为 0。

empty() 方法返回一个布尔值,表示字符串是否为空。如果字符串为空,则返回 true;否则返回 false。 

string str = "Hello";
// 判断字符串是否为空
if (str.empty()) {cout << "The string is empty." << endl;
}
else {cout << "The string is not empty." << endl;
}

3.string插入、追加  、拼接

1.运算符+=  、append

实现字符串的拼接

 string str = "Hello";// 使用运算符+=,append拼接新的字符串str += " World!";str.append(" World!");

 无论是使用运算符+=还是append()方法,都可以实现字符串的拼接。选择使用哪种方式取决于个人偏好和代码的可读性

2. push_back

向字符串末尾添加一个新的字符

string str = "Hello";
// 向字符串末尾添加新的字符
str.push_back('!');
3.insert 

在字符串的指定位置之前插入字符、子字符串或其他字符串

basic_string& insert(size_type pos, const basic_string& str);
basic_string& insert(size_type pos, const basic_string& str, size_type pos1, size_type n);
basic_string& insert(size_type pos, const CharT* cstr);
basic_string& insert(size_type pos, const CharT* cstr, size_type n);
basic_string& insert(size_type pos, size_type n, CharT c);
iterator insert(const_iterator p, size_type n, CharT c);
template<class InputIterator>
iterator insert(const_iterator p, InputIterator first, InputIterator last);
string str = "Hello world";
// 在位置 5 插入一个空格
str.insert(5, " ");
// 在位置 6 插入子字符串 "beautiful"
str.insert(6, "beautiful", 0, 9);

 注意,该操作时间复杂度较高,应少用

 4.string删除、替换

1.erase

删除字符串中的字符或子字符串

basic_string& erase(size_type pos = 0, size_type n = npos);
iterator erase(const_iterator p);
iterator erase(const_iterator first, const_iterator last);

参数 pos 表示要删除的起始位置,参数 n 表示要删除的字符数。通过 erase() 方法,可以删除指定位置或指定区间的字符或子字符

string str = "Hello world";
// 删除位置 5 开始的 6 个字符
str.erase(5, 6);
// 删除最后一个字符
str.erase(str.end() - 1);
2.pop_back

删除最后一个字符

string str = "Hello";
// 删除最后一个字符
str.pop_back();
3. replace

替换字符串中的字符或子字符串

basic_string& replace(size_type pos, size_type count, const basic_string& str);
basic_string& replace(const_iterator first, const_iterator last, const basic_string& str);
basic_string& replace(size_type pos, size_type count, const basic_string& str, size_type pos2, size_type count2);
basic_string& replace(size_type pos, size_type count, const CharT* cstr, size_type count2);
basic_string& replace(const_iterator first, const_iterator last, const CharT* cstr, size_type count2);
basic_string& replace(size_type pos, size_type count, const CharT* cstr);
basic_string& replace(const_iterator first, const_iterator last, const CharT* cstr);
basic_string& replace(size_type pos, size_type count, size_type count2, CharT ch);
basic_string& replace(const_iterator first, const_iterator last, size_type count2, CharT ch);
template<class InputIterator>
basic_string& replace(const_iterator first, const_iterator last, InputIterator first2, InputIterator last2);

参数 pos 表示要替换的起始位置,参数 count 表示要替换的字符数,参数 str 表示替换后的新字符串,参数 cstr 表示以空字符结尾的 C 风格字符串,参数 count2 表示要替换的字符数,参数 ch 表示要替换的单个字符。通过 replace() 方法,可以在指定位置替换字符或子字符串。 

string str = "Hello world";// 替换位置 6 开始的 5 个字符为 "beautiful"
str.replace(6, 5, "beautiful");

5.字符串操作

1.c_stl

获取字符串对象的以空字符结尾的 C 风格字符串。

const char* c_str() const noexcept;

通过调用 c_str() 方法,可以获取一个指向字符串对象的以空字符结尾的 C 风格字符串的指针。这个指针可以用于与需要 C 风格字符串作为参数的函数进行交互,或者直接打印输出字符串。

string str = "Hello";
// 获取 C 风格字符串指针
const char* cstr = str.c_str();

需要注意的是,通过 c_str() 方法获取的 C 风格字符串指针是只读的,不应该修改其中的内容。同时,在字符串对象生命周期结束之前,这个指针是有效的,但在字符串对象发生改变(如进行增删改操作)时,这个指针可能会变得无效。因此,在使用 c_str() 方法获取的指针时,应该注意有效性和不可修改性。

2.data

获取字符串对象的数据存储区域的指针。

const char* data() const noexcept;

通过调用 data() 方法,可以直接获取一个指向字符串对象数据存储区域的指针。这个指针可以用于与需要字符数组作为参数的函数进行交互,或者直接访问和修改字符串的内容。

需要注意的是,通过 data() 方法获取的指针并不保证以空字符结尾,因此在使用时应该谨慎处理。如果需要获取以空字符结尾的 C 风格字符串,可以使用 c_str() 方法。

string str = "Hello";// 获取数据存储区域指针
const char* pdata = str.data();// 修改第一个字符为 'h'
*pdata = 'h';
 3.copy

通过调用 copy() 方法,可以将字符串对象中的字符复制到指定的目标字符数组中

string str = "Hello";
char dest[10];// 复制字符串到目标字符数组
str.copy(dest, 5);// 在目标字符数组末尾添加空字符
dest[5] = '\0';
4.find、rfind

查找一个子串

size_t find(const std::string& str, size_t pos = 0) const noexcept;

 通过调用 find() 方法,可以在字符串对象中查找指定的子串,并返回子串第一次出现的位置。参数 str 是要查找的子串,pos 是查找的起始位置,默认为 0。

string str = "Hello, world!";// 查找子串 ", "
size_t pos = str.find(", ");// 如果找到,则截取子串前面的部分并打印输出
if (pos != std::string::npos) {cout << str.substr(0, pos) << std::endl;  // 输出 "Hello"
}

需要注意的是,如果 find() 方法没有找到指定的子串,它会返回 std::string::npos,这是一个常量,表示未找到。因此,在判断是否找到了子串时,应该使用 !=std::string::npos 的形式。 

 rfind() 方法和 find() 方法类似,但是它是从字符串的末尾开始查找子串或字符。

5.find_first_of、find_last_of

在字符串中查找参数中任何一个字符第一次出现的位置

size_t find_first_of(const std::string& str, size_t pos = 0) const noexcept;
size_t find_first_of(const char* s, size_t pos, size_t n) const noexcept;
size_t find_first_of(char c, size_t pos = 0) const noexcept;

可以传递一个字符串、一个字符数组或一个字符作为参数。这些函数会返回参数中任何一个字符第一次出现的位置,如果未找到则返回 std::string::npos。 

string str = "Hello, world!";
// 查找参数中任何一个字符第一次出现的位置
size_t pos1 = str.find_first_of("aeiou");
if (pos1 != std::string::npos) {cout << "First vowel found at position: " << pos1 << endl;
}
else {cout << "No vowels found" << endl;
}// 从指定位置开始查找参数中任何一个字符第一次出现的位置
size_t pos2 = str.find_first_of("aeiou", pos1 + 1);
if (pos2 != std::string::npos) {cout << "Next vowel found at position: " << pos2 << endl;
}
else {cout << "No more vowels found" << endl;
}

在这个示例中,我们首先使用 find_first_of 查找字符串中第一个元音字母的位置,然后从该位置的下一个字符开始继续查找下一个元音字母的位置。 

find_last_of与fi_first_of类似,用于在字符串中查找参数中任何一个字符最后一次出现的位置。

6.substr    子串处理

从当前字符串中提取子字符串

td::string substr(size_t pos = 0, size_t count = std::string::npos) const;
  • pos 参数指定要提取的子字符串的起始位置,默认为 0。
  • count 参数指定要提取的字符数目,默认为 std::string::npos,表示提取从起始位置到字符串末尾的所有字符。
string str = "Hello, world!";// 提取从第7个字符开始的子字符串
string sub1 = str.substr(6);
std::cout << "Substring starting from position 6: " << sub1 << endl;// 提取从第7个字符开始的3个字符
string sub2 = str.substr(6, 3);
cout << "Substring of length 3 starting from position 6: " << sub2 << endl;

3.string反转(reverse)

在 C++ 中,可以通过使用 std::reverse 算法来反转容器(比如 std::stringstd::vector 等)中的元素。

string str = "Hello, world!";// 反转字符串
reverse(str.begin(), str.end());

4.非成员函数 

1.getline(读取)

用于从输入流中读取一行文本的函数

cin不能读取带空格的字符串,getline可以

 std::string input;// 从标准输入中读取一行文本std::cout << "Please enter a line of text: ";std::getline(std::cin, input);// 输出读取的文本std::cout << "You entered: " << input << std::endl;
2.swap(交换)

用于交换两个字符串的内容。这个函数会以常数时间完成字符串的交换,因此比使用复制和赋值运算符更有效率。

string str1 = "Hello";
string str2 = "World";// 使用 std::string::swap 交换 str1 和 str2 的内容
str1.swap(str2);
3. relational operators(比较)

在 C++ 中,字符串 std::string 类型支持使用关系运算符(relational operators)进行比较操作。这些关系运算符可以用于比较两个字符串对象之间的大小关系,例如判断两个字符串是否相等、大小关系等。

以下是 std::string 类型支持的关系运算符:

  1. ==:检查两个字符串是否相等。
  2. !=:检查两个字符串是否不相等。
  3. <:检查一个字符串是否小于另一个字符串。
  4. >:检查一个字符串是否大于另一个字符串。
  5. <=:检查一个字符串是否小于或等于另一个字符串。
  6. >=:检查一个字符串是否大于或等于另一个字符串。

这些关系运算符可以在比较字符串时非常有用。例如,你可以使用这些运算符来对字符串进行字典序的比较,或者在排序算法中对字符串进行排序。

  std::string str1 = "apple";std::string str2 = "banana";if (str1 == str2) {std::cout << "str1 is equal to str2" << std::endl;} else if (str1 < str2) {std::cout << "str1 is less than str2" << std::endl;} else {std::cout << "str1 is greater than str2" << std::endl;}

5.访问遍历 

string的遍历有三种方式:1.下标 2.迭代器 3.范围for 

#include <iostream>
#include <string>
using namespace std;int main()
{string s1("hello world");//1.下标for (size_t i = 0; i < s1.size(); i++){cout << s1[i] << " ";}//2.迭代器string::iterator it = s1.begin();while (it != s1.end()){cout << *it << " ";++it;}//3.范围forfor (auto e : s1){cout << e << " ";}return 0;
}

 6.静态成员常量(npos)

nposstd::string 类型中的一个静态成员常量,它通常被用来表示字符串中没有匹配项或者没有找到所寻找的子串的位置。npos 通常被定义为 std::string::npos,其值为一个特定的整数(通常是 -1 或者是一个很大的正整数),这个整数的值可以保证不会和有效的字符串下标产生冲突

举个例子,当你在字符串中查找某个子串时,如果没有找到这个子串,则返回的位置是 std::string::npos。在 std::string::find() 函数中,如果找到了子串,那么它会返回子串在字符串中的位置,否则会返回 std::string::npos

                                   以上就是本篇文章的全部内容,谢谢观看

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/255941.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

16 亚稳态原理和解决方案

1. 亚稳态原理 亚稳态是指触发器无法在某个规定的时间段内到达一个可以确认的状态。在同步系统中&#xff0c;输入总是与时钟同步&#xff0c;因此寄存器的setup time和hold time是满足的&#xff0c;一般情况下是不会发生亚稳态情况的。在异步信号采集中&#xff0c;由于异步…

寒假9-蓝桥杯训练

//轨道炮 #include<iostream> using namespace std; #include<algorithm> int logs[100010]; int main() {int n;cin >> n;for (int i 1;i < n;i){cin >> logs[i];}sort(logs 1, logs n 1);int ans 1000000000;for (int i 2;i < n;i){if (…

【数学建模】【2024年】【第40届】【MCM/ICM】【F题 减少非法野生动物贸易】【解题思路】

一、题目 &#xff08;一&#xff09; 赛题原文 2024 ICM Problem F: Reducing Illegal Wildlife Trade Illegal wildlife trade negatively impacts our environment and threatens global biodiversity. It is estimated to involve up to 26.5 billion US dollars per y…

分布式系统架构介绍

1、为什么需要分布式架构&#xff1f; 增大系统容量&#xff1a;单台系统的性能瓶颈&#xff0c;多台机器才能应对大规模的应用场景&#xff0c;所以就需要我们的应用支撑平台具备分布式架构。 加强系统的可用&#xff1a;为了满足业务的SLA要求&#xff0c;需要通过分布式架构…

深度学习(13)--PyTorch搭建神经网络进行气温预测

一.搭建神经网络进行气温预测流程详解 1.1.导入所需的工具包 import numpy as np # 矩阵计算 import pandas as pd # 数据读取 import matplotlib.pyplot as plt # 画图处理 import torch # 构建神经网络 import torch.optim as optim # 设置优化器 1.2.读取并处理数据…

第五篇:MySQL常见数据类型

MySQL中的数据类型有很多&#xff0c;主要分为三类:数值类型、字符串类型、日期时间类型 三个表格都在此网盘中&#xff0c;需要者可移步自取&#xff0c;如果觉得有帮助希望点个赞~ MySQL常见数据类型表 数值类型 &#xff08;注&#xff1a;decimal类型举例&#xff0c;如1…

DevOps:CI、CD、CB、CT、CD

目录 一、软件开发流程演化快速回顾 &#xff08;一&#xff09;瀑布模型 &#xff08;二&#xff09;原型模型 &#xff08;三&#xff09;螺旋模型 &#xff08;四&#xff09;增量模型 &#xff08;五&#xff09;敏捷开发 &#xff08;六&#xff09;DevOps 二、走…

【开源】SpringBoot框架开发天沐瑜伽馆管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 瑜伽课程模块2.3 课程预约模块2.4 系统公告模块2.5 课程评价模块2.6 瑜伽器械模块 三、系统设计3.1 实体类设计3.1.1 瑜伽课程3.1.2 瑜伽课程预约3.1.3 系统公告3.1.4 瑜伽课程评价 3.2 数据库设计3.2.…

【Kubernetes】kubectl top pod 异常?

目录 前言一、表象二、解决方法1、导入镜像包2、编辑yaml文件3、解决问题 三、优化改造1.修改配置文件2.检查api-server服务是否正常3.测试验证 总结 前言 各位老铁大家好&#xff0c;好久不见&#xff0c;卑微涛目前从事kubernetes相关容器工作&#xff0c;感兴趣的小伙伴相互…

【Kubernetes】在k8s1.24及以上版本基于containerd容器运行时测试pod从harbor拉取镜像

基于containerd容器运行时测试pod从harbor拉取镜像 1、安装高版本containerd2、安装docker3、登录harbor上传镜像4、从harbor拉取镜像 1、安装高版本containerd 集群中各个节点都要操作 yum remove containerd.io -y yum install containerd.io-1.6.22* -y cd /etc/containe…

《UE5_C++多人TPS完整教程》学习笔记2 ——《P3 多人游戏概念(Multiplayer Concept)》

本文为B站系列教学视频 《UE5_C多人TPS完整教程》 —— 《P3 多人游戏概念&#xff08;Multiplayer Concept&#xff09;》 的学习笔记&#xff0c;该系列教学视频为 Udemy 课程 《Unreal Engine 5 C Multiplayer Shooter》 的中文字幕翻译版&#xff0c;UP主&#xff08;也是译…

数据结构:并查集讲解

并查集 1.并查集原理2.并查集实现3.并查集应用4.并查集的路径压缩 1.并查集原理 在一些应用问题中&#xff0c;需要将n个不同的元素划分成一些不相交的集合。开始时&#xff0c;每个元素自成一个单元素集合&#xff0c;然后按一定的规律将归于同一组元素的集合合并。在此过程中…

分享88个鼠标特效,总有一款适合您

分享88个鼠标特效&#xff0c;总有一款适合您 88个鼠标特效下载链接&#xff1a;https://pan.baidu.com/s/1ljcxwgXGpw7baiufUGJjZA?pwd8888 提取码&#xff1a;8888 Python采集代码下载链接&#xff1a;采集代码.zip - 蓝奏云 学习知识费力气&#xff0c;收集整理更不…

5G NR 频率计算

5G中引入了频率栅格的概念&#xff0c;也就是小区中心频点和SSB的频域位置不能随意配置&#xff0c;必须满足一定规律&#xff0c;主要目的是为了UE能快速的搜索小区&#xff1b;其中三个最重要的概念是Channel raster 、synchronization raster和pointA。 1、Channel raster …

Hive正则表达式

Hive版本&#xff1a;hive-3.1.2 一、Hive的正则表达式概述 正则表达式是一种用于匹配和操作文本的强大工具&#xff0c;它是由一系列字符和特殊字符组成的模式&#xff0c;用于描述要匹配的文本模式。 Hive的正则表达式灵活使用解决HQL开发过程中的很多问题&#xff0c;本篇文…

H12-821_26

26.下列选项中,哪些路由前缀满足下面的IP-Prefix条件? A.20.0.1.0/24 B.20.0.1.0/23 C.20.0.1.0/25 D.20.0.1.0/28 答案&#xff1a;ACD 注释&#xff1a; 前缀列表可以匹配路由前缀和网络掩码。 ip ip-prefix test index 10 permit 20.0.0.0 16 greater-equal 24 less-equal…

Zephyr NRF7002 实现AppleJuice

BLE的基础知识 ble的信道和BR/EDR的信道是完全不一样的。但是范围是相同的&#xff0c;差不多也都是2.4Ghz的频道。可以简单理解为空中有40个信道0~39信道。两个设备在相同的信道里面可以进行相互通信。 而这些信道SIG又重新编号&#xff1a; 这个编号就是把37 38 39。 3个信道…

Seurat - 聚类教程 (1)

设置 Seurat 对象 在本教程[1]中&#xff0c;我们将分析 10X Genomics 免费提供的外周血单核细胞 (PBMC) 数据集。在 Illumina NextSeq 500 上对 2,700 个单细胞进行了测序。可以在此处[2]找到原始数据。 我们首先读取数据。 Read10X() 函数从 10X 读取 cellranger 管道的输出&…

Linux network namespace 访问外网以及多命名空间通信(经典容器组网 veth pair + bridge 模式认知)

写在前面 整理K8s网络相关笔记博文内容涉及 Linux network namespace 访问外网方案 Demo实际上也就是 经典容器组网 veth pair bridge 模式理解不足小伙伴帮忙指正 不必太纠结于当下&#xff0c;也不必太忧虑未来&#xff0c;当你经历过一些事情的时候&#xff0c;眼前的风景已…

数据结构第十四天(树的存储/双亲表示法)

目录 前言 概述 接口&#xff1a; 源码&#xff1a; 测试函数&#xff1a; 运行结果&#xff1a; 往期精彩内容 前言 孩子&#xff0c;一定要记得你的父母啊&#xff01;&#xff01;&#xff01; 哈哈&#xff0c;今天开始学习树结构中的双亲表示法&#xff0c;让孩…