C++:string类(第二章)

ops/2024/9/23 13:12:22/

hello,各位小伙伴,本篇文章跟大家一起学习《C++:string类》,感谢大家对我上一篇的支持,如有什么问题,还请多多指教 !
如果本篇文章对你有帮助,还请各位点点赞!!!
在这里插入图片描述

话不多说,开始进入正题

文章目录

  • :rocket:sort函数
  • :rocket:string类对象的修改操作
    • :airplane:1.push_back
    • :airplane:2.append
    • :airplane:3.insert
    • :airplane:4.assign
    • :airplane:5.operator+=
    • :airplane:6.c_str
    • :airplane:7.find
    • :airplane:8.rfind
    • :airplane:9.substr
    • :airplane:小笔记
  • :rocket:string类对象的容量操作
    • :airplane:1.reverse
    • :airplane:2.resize

🚀sort函数

sort函数是用来排序的函数,但是,sort不仅仅是排序字符或者数字。
template
void sort (RandomAccessIterator first, RandomAccessIterator last);

template <class RandomAccessIterator, class Compare>
void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);

sort被包含在<algorithm>头文件里

可以看到sort是通过迭代器来对所有的容器进行排序,而且给出来是函数模板,也就是说可以传各种类型的迭代器,当然也是有要求的,要求是随机迭代器(以后会讲)。

传参为迭代区间,在C++里有一个要求,但凡是迭代区间,都是需要左闭右开(即 [first,last)),所以last不是一个有效数据,代码举例:

#include<algorithm>
int main()
{string s = "sijghrywunbpmkzhg";cout << s << endl << endl;sort(s.begin(), s.end());cout << s << endl;
}

想对数据哪一段排序就控制迭代器区间,一定要记住左闭右开

🚀string类对象的修改操作

✈️1.push_back

void push_back (char c);
尾插一个字符,举例代码:

int main()
{string s = "hello world";cout << s << endl << endl;s.push_back('a');cout << s << endl;
}

✈️2.append

1.🔥
string& append (const string& str);
尾插一个string类对象

string s1 = "hello ";
string s2 = "world";
s1.append(s2);

2.🔥
string& append (const string& str, size_t subpos, size_t sublen);
尾插一个string类对象的一部分

string s1 = "hello ";
string s2 = "world";
s1.append(s2, 2, 3);

3.🔥
string& append (const char* s);
尾插一个字符串

string s1 = "hello ";
const char* s2 = "world";
s1.append(s2);

4.🔥
string& append (const char* s, size_t n);
尾插一个字符串中的前几个字符

string s1 = "hello ";
const char* s2 = "world";
s1.append(s2, 3);

5.🔥
string& append (size_t n, char c);
尾插nc字符

string s1 = "hello ";
char ch = 'a';
s1.append(3, ch);

6.🔥
template string& append (InputIterator first, InputIterator last);
迭代器区间传参方式,要记住左闭右开

	string s1 = "hello ";string s2 = "world";cout << s1 << endl << endl;s1.append(s2.begin(),s2.end());cout << s1 << endl;

✈️3.insert

在指定位置插入字符或者字符串。
string (1)
string& insert (size_t pos, const string& str);

substring (2) string& insert (size_t pos, const string& str, size_t subpos, size_t sublen); c-string (3) string& insert (size_t pos, const char* s); buffer (4) string& insert (size_t pos, const char* s, size_t n); fill (5) string& insert (size_t pos, size_t n, char c); void insert (iterator p, size_t n, char c); single character (6) iterator insert (iterator p, char c); range (7) template void insert (iterator p, InputIterator first, InputIterator last);

代码写法与C++:string(第一章)里所讲的string初始化类似。

但是insert的时间复杂度为O(N),因为需要挪动数据,所以能少用就少用。

✈️4.assign

为字符串指定一个新值,替换其当前内容。(相当于重新赋予一个值)
在这里插入图片描述
但是一般很少用,了解一下即可。

✈️5.operator+=

string (1)
string& operator+= (const string& str);

c-string (2)
string& operator+= (const char* s);

character (3)
string& operator+= (char c);

在字符串后追加字符串str或者字符ch。
操作很简单,如:

string str = "hello ";
char ch = 'a';
str += ch;

✈️6.c_str

const char* c_str() const;
返回C格式字符串。

返回一个指向数组的指针,该数组包含一个以null结尾的字符序列(即C字符串),表示字符串对象的当前值。此数组包含组成字符串对象值的相同字符序列,加上末尾的附加终止null字符(“\0”)。

代码例子:

string s1 = "abcd";
const char* ch = s1.c_str();
while (*ch != '\0')
{cout << *ch;++ch;
}

要注意:可以看到s1.c_str()返回的是const char*的指针,所以是不能对其进行修改的。

✈️7.find

从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置。
string (1) //找string类
size_t find (const string& str, size_t pos = 0) const;

c-string (2) //找字符数组
size_t find (const char* s, size_t pos = 0) const;

buffer (3) //在字符串中搜索指定的子字符串
size_t find (const char* s, size_t pos, size_t n) const;

character (4) //找字符
size_t find (char c, size_t pos = 0) const;

  • str为要找的字符串
  • pos为寻找的起始位置(下标)
  • s为字符指针(指向的字符串)

代码例子:

	string s1 = "hello";const char* s2 = "lloododo";//寻找s2前两个字符组成的字符串在s1中的位置int index = s1.find(s2, 0,2);cout << index << endl;

✈️8.rfind

从字符串pos位置开始往前找字符c,返回该字符在字符串中的位置。
string (1)
size_t rfind (const string& str, size_t pos = npos) const;

c-string (2)
size_t rfind (const char* s, size_t pos = npos) const;

buffer (3)
size_t rfind (const char* s, size_t pos, size_t n) const;

character (4)
size_t rfind (char c, size_t pos = npos) const;

find不同的是,rfind是从后面开始往前找,代码例子:

	string s1 = "hello";char ch = 'l';int index = s1.rfind(ch, s1.length()-1);cout << index << endl;

要注意:输出结果为3,也就是rfind找的是从后面往前第一次出现的下标位置。

✈️9.substr

string substr (size_t pos = 0, size_t len = npos) const;
在str中从pos位置开始,截取n个字符,然后将其返回。

代码举例:

	string s1 = "hello";string s2 = s1.substr(0, 3);cout << s2 << endl;

✈️小笔记

1. 在string尾部追加字符时,s.push_back© / s.append(1, c) / s += 'c’三种的实现方式差不多,一般情况下string类的+=操作用的比较多,+=操作不仅可以连接单个字符,还可以连接字符串。
2. 对string操作时,如果能够大概预估到放多少字符,可以先通过reserve把空间预留好。

🚀string类对象的容量操作

✈️1.reverse

void reserve (size_t n = 0);
功能:请求字符串容量适应最大长度为n个字符的计划大小更改(主要是为字符串预留空间),代码如下:

int main()
{string s1("abcd");cout << "capacity-> " << s1.capacity() << endl;cout << "size-> " << s1.size() << endl << endl;s1.reserve(20);cout << "capacity-> " << s1.capacity() << endl;cout << "size-> " << s1.size() << endl;return 0;
}

可以看到s1capacity发生了改变,但是size没有发生改变,是因为reverse是只改变capacity的。

还要注意的一点是:reverse给与的空间可能会比你所给的大,是因为在分配空间时,不同编译器会有不同的方式来扩容。

抛出一个问题:如果我们传入的空间比原来的小,会发生缩容吗?
如下测试代码:

int main()
{string s1("abcdxxxxxxxxxxxxxxxxxxxxxxxxx");cout << "capacity-> " << s1.capacity() << endl;s1.reserve(100);cout << "capacity-> " << s1.capacity() << endl;s1.reserve(10);cout << "capacity-> " << s1.capacity() << endl;return 0;
}

在VS2022编译器下是不会的:
在这里插入图片描述
但是在VS2019是会发生缩容的,所以,是否缩容其实是取决于编译器的。

✈️2.resize

void resize (size_t n);
void resize (size_t n, char c);

将字符串的大小调整为n个字符的长度,

如果n小于当前字符串长度,则当前值将缩短为其第一个n个字符,删除第n个字符之后的字符。

如果n大于当前字符串长度,则通过在末尾插入所需数量的字符以达到n的大小来扩展当前内容。如果指定了c,则将新元素初始化为c的副本,否则,它们是值初始化字符(null字符)。

代码如下:

int main()
{string s1("abcdxxxxxxxxxxxxxxxxxxxxxxxxx");cout << "size-> " << s1.size() << endl;cout << "capacity-> " << s1.capacity() << endl << endl;s1.resize(100);cout << "size-> " << s1.size() << endl;cout << "capacity-> " << s1.capacity() << endl;return 0;
}

可以看到s1size变大了,并且capacity也变大了,很容易理解,因为s1变大,所需要的存储空间自然也就要变大,假如代码这样写:

int main()
{string s1("abcdxxxxxxxxxxxxxxxxxxxxxxxxx");cout << "size-> " << s1.size() << endl;cout << "capacity-> " << s1.capacity() << endl << endl;s1.resize(100, 'a');cout << "size-> " << s1.size() << endl;cout << "capacity-> " << s1.capacity() << endl;return 0;
}

在这里插入图片描述
不够,那就a来补,因为在传参时第二个参数传了a

那代码是这样:

int main()
{string s1("abcdxxxxxxxxxxxxxxxxxxxxxxxxx");cout << "size-> " << s1.size() << endl;cout << "capacity-> " << s1.capacity() << endl << endl;s1.resize(100,'a');cout << "size-> " << s1.size() << endl;cout << "capacity-> " << s1.capacity() << endl;cout << s1 << endl << endl;s1.resize(10);cout << "size-> " << s1.size() << endl;cout << "capacity-> " << s1.capacity() << endl;cout << s1 << endl;
}

在这里插入图片描述
是的,s1中下标为size_t n - 1(代码中为10 - 1)以后的字符会被删除。
s1的大小被缩小,所以s1的数据只能被裁剪,导致数据丢失。

你学会了吗?
好啦,本章对于《C++:string类(第二章)》的学习就先到这里,如果有什么问题,还请指教指教,希望本篇文章能够对你有所帮助,我们下一篇见!!!

如你喜欢,点点赞就是对我的支持,感谢感谢!!!

请添加图片描述


http://www.ppmy.cn/ops/37212.html

相关文章

双ISP住宅IP有何优势?

双ISP住宅IP在当前的互联网环境中具有显著的优势&#xff0c;这些优势主要体现在网络连接的稳定性、安全性、速度以及业务适用范围等方面。以下是对双ISP住宅IP优势的详细分析&#xff1a; 第一点网络连接的稳定性&#xff0c;双ISP住宅IP使用两个不同的互联网服务提供商&…

常用邮箱汇总

01. 临时邮箱 24小时邮箱&#xff1a;http://24mail.chacuo.net60分钟邮箱&#xff1a;https://www.guerrillamail.com/zh/10 分钟邮箱&#xff1a;https://linshiyouxiang.net/10 分钟邮箱&#xff1a;https://temp-mail.org/zh/10 分钟邮箱&#xff1a;https://10minutemail…

windows安装ElasticSearch以及踩坑

1.下载 elasticsearch地址&#xff1a;Past Releases of Elastic Stack Software | Elastichttps://www.elastic.co/cn/downloads/past-releases#elasticsearch IK分析器地址&#xff1a;infinilabs/analysis-ik: &#x1f68c; The IK Analysis plugin integrates Lucene IK…

淤地坝安全监测预警系统解决方案

一、方案背景 淤地坝是黄土高原地区人民群众长期同水土流失斗争实践中创造的一种行之有效的水土保持工程措施&#xff0c;在拦泥保土、减少入黄泥沙、防洪减灾、淤地造田、巩固退耕还林&#xff08;草&#xff09;、保障生态安全、促进粮食生产和水资源合理利用及经济社会稳定发…

C语言头文件的引入使用<>和““有什么区别

在C语言中&#xff0c;引入头文件时使用<>和""有以下主要区别&#xff1a; 搜索路径不同&#xff1a; 当使用#include <filename.h>时&#xff0c;编译器会首先在系统目录中搜索头文件。这些系统目录通常包含了标准库的头文件&#xff0c;如stdio.h、std…

lsof 查看进程是被哪个文件占用

要查看进程被哪个文件占用&#xff0c;可以使用lsof命令&#xff08;list open files&#xff09;。可以使用以下命令来查看指定进程的打开文件&#xff1a; lsof -p <PID>其中&#xff0c;<PID>是要查询的进程的进程ID。这将列出指定进程打开的所有文件。如果想查…

【七十九】【算法分析与设计】并查集模板!!!并查集的实现_牛客题霸_牛客网,【模板】并查集 - 洛谷,并查集代码!!!

并查集的实现_牛客题霸_牛客网 描述 给定一个没有重复值的整形数组arr&#xff0c;初始时认为arr中每一个数各自都是一个单独的集合。请设计一种叫UnionFind的结构&#xff0c;并提供以下两个操作。 boolean isSameSet(int a, int b): 查询a和b这两个数是否属于一个集合 void u…

Qt :信号与槽

信号与槽 信号介绍connect 函数使用connect 函数传参问题 定义槽&#xff08;solt&#xff09;函数方法一方法二 定义信号关键字 signals、emit 定义带参数的信号和槽参数个数不一致问题断开信号和槽的连接 disconnect lambda 表达式 信号介绍 Qt 中&#xff0c;信号会涉及三个…