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);
尾插n
个c
字符
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);
代码写法与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;}
可以看到s1
的capacity
发生了改变,但是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;}
可以看到s1
的size
变大了,并且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类(第二章)》的学习就先到这里,如果有什么问题,还请指教指教,希望本篇文章能够对你有所帮助,我们下一篇见!!!
如你喜欢,点点赞就是对我的支持,感谢感谢!!!