【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是反向迭代器

具体操作请看目录 5.访问遍历

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.hqwc.cn/news/466205.html

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

相关文章

【激光SLAM】激光雷达数学模型和运动畸变去除

目录 概念介绍激光雷达传感器介绍测距原理三角测距飞行时间&#xff08;TOF) 激光雷达数学模型介绍光束模型&#xff08;beam model&#xff09;似然场模型&#xff08;likelihood model&#xff09; 运动畸变介绍 畸变去除纯估计方法&#xff08;ICP Variants)ICP方法VICP&…

生态位模拟——草稿笔记

文章目录 前言ENM初识一、所需软件安装1.1. 下载ArcGIS软件&#xff1a;1.2. 下载 MaxEnt软件&#xff1a;1.3. 下载ENMtools&#xff1a; 二、数据准备与处理2.1. 物种分布数据2.2. 环境因子数据2.3. 地图数据2.4. 物种分布点去冗余2.4.1. 使用spThin包中的thin函数2.4.2. 或者…

利用Python和pandas库进行股票技术分析:移动平均线和MACD指标

利用Python和pandas库进行股票技术分析&#xff1a;移动平均线和MACD指标 介绍准备工作数据准备计算移动平均线计算MACD指标结果展示完整代码演示 介绍 在股票市场中&#xff0c;技术分析是一种常用的方法&#xff0c;它通过对股票价格和交易量等历史数据的分析&#xff0c;来…

FANUC机器人如何清除示教器右上角的白色感叹号?

FANUC机器人如何清除示教器右上角的白色感叹号&#xff1f; 如下图所示&#xff0c;示教器上显示白色的感叹号&#xff0c;如何清除呢&#xff1f; 具体可参考以下步骤&#xff1a; 按下示教器上白色的“i”键&#xff0c;如下图所示&#xff0c; 如下图所示&#xff0c;按…

配置DNS正反向解析服务!!!!

一.准备工作 #关闭防火墙和selinux,或者允许服务通过 [rootnode ~]# nmcli c mod ens32 ipv4.method manual ipv4.address 192.168.32.133/24 ipv4.gateway 192.168.32.2 ipv4.dns 192.168.32.132 [rootnode ~]# nmcli c reload [rootnode ~]# nmcli c up ens32[rootnode ~]# …

【计算几何】确定两条连续线段向左转还是向右转

确定两条连续线段向左转还是向右转 目录 一、说明二、算法2.1 两点的叉积2.2 两个段的叉积 三、旋转方向判别3.1 左转3.2 右转3.3 共线判别 一、说明 如果是作图&#xff0c;或者是判别小车轨迹。为了直观地了解&#xff0c;从当前点到下一个点过程中&#xff0c;什么是左转、…

【芯片设计- RTL 数字逻辑设计入门 12 -- verilog 有符号数加减法】

文章目录 多功能数据处理器描述verilog 无符号数与有符号数8d100 8d1558d100 8d1568d100 8d157verilog 代码实现TestBench 代码VCS 仿真结果 多功能数据处理器描述 根据指示信号select的不同&#xff0c;对输入信号a,b实现不同的运算。输入信号a,b为8bit有符号数&#xff1…

【后端高频面试题--Linux篇】

&#x1f680; 作者 &#xff1a;“码上有前” &#x1f680; 文章简介 &#xff1a;后端高频面试题 &#x1f680; 欢迎小伙伴们 点赞&#x1f44d;、收藏⭐、留言&#x1f4ac; 后端高频面试题--Linux篇 Windows和Linux的区别&#xff1f;Unix和Linux有什么区别&#xff1f…

[Python进阶] 制作动态二维码

11.1 制作动态二维码 二维码&#xff08;QR code&#xff09;是一种二维条形码&#xff08;bar code&#xff09;&#xff0c;它的起源可以追溯到20世纪90年代初。当时&#xff0c;日本的汽车工业开始使用一种被称为QR码的二维条码来追踪汽车零部件的信息。 QR码是Quick Respo…

i.MX6ULL 嵌入式学习(一)

i.MX6ULL 嵌入式学习(一) i.MX6ULL理论知识 i.MX6ULL 嵌入式学习(一)进程psipc 进程间通信管道信号(类似中断)system-V 消息队列system-V 信号量system-V 共享内存 进程 创建进程(复制)&#xff0c;同程序 fork #include<unistd.h> a. 返回值 成功 0 或 非负非零整数( 父…

红队打靶练习:DEVGURU: 1

目录 信息收集 1、arp 2、nmap 3、dirsearch WEB web信息收集 8585端口 漏洞利用 提权 系统信息收集 横向渗透 get flag 信息收集 1、arp ┌──(root㉿ru)-[~/kali] └─# arp-scan -l Interface: eth0, type: EN10MB, MAC: 00:50:56:20:80:1b, IPv4: 192.168.10…