【Cpp::STL】标准模板库_ string详解

水墨不写bug 2024-06-11 09:05:06 阅读 73

标题:【Cpp::STL】标准模板库_ string详解

@水墨不写bug



目录

前言:创作感悟即更新方向预告

(一)string简介

 (二)容器介绍

(1)成员变量

(2)成员函数 

 i,构造函数string()

ii,析构函数~string()

iii,赋值重载

iv,迭代器

a,begin()

b,end()

c,rbegin()

d,rend()

e,cbegin()

f,cend()

g,crbegin()

h,crend()

v,容量和长度

a,size()

b,lenth()

c,max_size()

d,resize()

e,capacity()

f,reserve()

g,clear()

h,empty()

i,shrink_to_fit()

vi,元素访问

a,operator[]

b,at()

c,back()

d,front()

vii,修改方式

a,operator+=()

b,append()

c,push_back()

d,assign()

        将一个新值赋给字符串,替换其当前内容。

e,insert()

f,erase()

g,replace()

h,swap()

i,pop_back()

viii,串操作

a,c_str()

b,data()

c,get_allocator()

d,copy()

e,find()

f,rfind()

g,find_first_of()

h,find_last_of()

i,find_first_not_of()

j,find_last_not_of()

k,substr()

l,compare()

ix,成员常量

npos


前言:创作感悟即更新方向预告

        从C语言到C++,这一路走来,我们遇到了不少困难,并一路克服了他们。

        在刚接触C语言时,我们甚至觉得想要写对一句C语言代码都十分困难,但是随着练习的增多,我们在熟悉了基本语法之后,又遇到了C语言阶段的第一个拦路虎:《指针》。在指针阶段我们从不同层次,不同方面认识了:一级指针,二级指针;指针数组,数组指针;函数指针,函数指针数组等。

        在克服指针之后,我们就来到了比较平缓的区域,那时,我们主要学习了一些C的其他的小的语法。填填补补,讨论了一些学习者在学习C语言时其他的重要的问题。

        后来,我们再一次攀登了数据结构的高峰,数据结构是现实的一些问题的抽象出来的数据在计算机中的存储方式,数据结构是为了解决现实的一些问题,为了方便表示现实中的一些问题的数据而设计的。

        在数据结构阶段,我们熟悉了顺序表,单链表,栈,队列,带头双向循环链表,堆,二叉树等基本数据结构,并用C语言在底层实现了它们,这为我们深入学习高阶数据结构(后期会更新)奠定了坚实的基础!数据结构虽然困难,在能力区之外才能提升自己。

        之后,我们又从底层了解了常用排序:冒泡排序,插入排序,选择排序,堆排序,快速排序,希尔排序,归并排序等。通过C语言实现这些排序算法,我们对这些排序的适用情形,底层原理都有了深入的认识。

        接下来在进入C++学习之后,我们发现C++更加智能了,一些基本的数据结构不需要我们手搓实现了,但是我们对基本数据结构的认识仍然会对我们的学习提供莫大的帮助!STL提供的数据结构的设计原理和理由我们都可以一一道出。

        在此阶段,我们将进入C++的标准模板库的学习,深入剖析STL的原理。接下来,我会逐一表达我对STL的常用容器的理解:string(姑且算是容器)、vector、list、map、set、unordered_map等等。

希望接下来的内容对你的学习有所帮助!


(一)string简介

        string类是存储字符串类型的类。

        标准string类为这种对象提供了类似于标准字节容器的接口,但增加了专门用于操作单字节字符的字符串的功能。

The standard string class provides support for such objects with an interface similar to that of a standard container of bytes, but adding features specifically designed to operate with strings of single-byte characters.

        string类是basic_string类模板的实例化,basic_string类模板使用char(即bytes)作为其字符类型,其默认的char_traits和allocator类型(有关模板的更多信息,请参阅basic_string)。

The string class is an instantiation of the basic_string class template that uses char (i.e., bytes) as its character type, with its default char_traits and allocator types (see basic_string for more info on the template).

        请注意,这个类处理字节时与使用的编码无关:如果用于处理多字节或变长字符序列(如UTF-8),该类的所有成员(如length或size)以及它的迭代器仍将以字节(而不是实际编码的字符)为单位进行操作。

Note that this class handles bytes independently of the encoding used: If used to handle sequences of multi-byte or variable-length characters (such as UTF-8), all members of this class (such as length or size), as well as its iterators, will still operate in terms of bytes (not actual encoded characters).

 (二)容器介绍

(1)成员变量

member type definition
value_type char
traits_type char_traits<char>
allocator_type allocator<char>
reference char&
const_reference const char&
pointer char*
const_pointer const char*
iterator a random access iterator to char (convertible to const_iterator)
const_iterator a random access iterator to const char
reverse_iterator reverse_iterator<iterator>
const_reverse_iterator reverse_iterator<const_iterator>
difference_type ptrdiff_t
size_type size_t

(待更新) 

(2)成员函数 


 i,构造函数string()

default (1)

string();

默认构造,创建一个空串,这个空串的长度是0;

#include<iostream>#include<string>using namespace std;int main(){string s1;cout<<s1.length()<<endl; //输出结果是0return 0;}

copy (2)

string (const string& str);

拷贝构造,通过已有对象拷贝构造一个新的对象,这个对象和已有对象在逻辑上是相同的。

#include<iostream>#include<string>using namespace std;int main(){string s1;string s2(s1);string s3 = s1;// 这两种都称为拷贝构造return 0;}

substring (3)

string (const string& str, size_t pos, size_t len = npos);

通过子串构造,由str的下标pos位置开始的len个字符来构造。

#include<iostream>#include<string>using namespace std;int main(){string s1("mywtrdisnmop");string s2(s1,2,3);cout<<s2<<endl; //输出wtrreturn 0;}

from c-string (4)

string (const char* s);

通过C类型的字符串来构造,形式类似默认构造传入字符串类型参数。

#include<iostream>#include<string>using namespace std;int main(){string s1("mywtrdisnmop");cout<<s1<<endl; //输出mywtrdisnmopreturn 0;}

from buffer (5)

string (const char* s, size_t n);

通过C字符串的子串来构造。

#include<iostream>#include<string>using namespace std;int main(){const char* s = "helopuhde";string s1(s,5);cout<<s1<<endl;//输出helopreturn 0;}

fill (6)

string (size_t n, char c);

通过一个字符来构造,一个字符重复n次。

#include<iostream>#include<string>using namespace std;int main(){string s1(5,'r');cout<<s1<<endl;//输出rrrrrreturn 0;}

%%考虑到代码的简洁性,下面的代码展示仅展示有效的部分,比如:

#include<iostream>#include<string>using namespace std;int main(){string s1(5,'r');cout<<s1<<endl;//输出rrrrrreturn 0;}

 省略为:

int main(){string s1(5,'r');cout<<s1<<endl;//输出rrrrrreturn 0;}

(省去了头文件的包含和展开命名空间) %%


ii,析构函数~string()

        销毁string实例化的对象。


iii,赋值重载

string (1)

string& operator= (const string& str);

实现对象之间的赋值操作。

int main(){string s1("hello");string s2;s2 = s1;cout<<s2<<endl;//输出helloreturn 0;}

c-string (2)

string& operator= (const char* s);

实现将C字符串给对象赋值操作。

int main(){const char* s1 = "helloC";string s2;s2 = s1;cout<<s2<<endl;//输出helloCreturn 0;}

character (3)

string& operator= (char c);

实现将字符给对象赋值。

int main(){char ch = 'g';string s2;s2 = ch;cout<<s2<<endl;//输出greturn 0;}


iv,迭代器

a,begin()

iterator begin();const_iterator begin() const;

        统一返回string对象的字符串的首地址,分为普通类型和const类型,const类型的迭代器不能通过迭代器修改string对象。


b,end()

iterator end();const_iterator end() const;

        统一返回string对象的字符串的最后一个字符的地址,分为普通类型和const类型,const类型的迭代器不能通过迭代器修改string对象。


 

c,rbegin()

reverse_iterator rbegin();const_reverse_iterator rbegin() const;

        反向迭代器,rbegin()返回对象的最后一个字符的地址,rbegin()的自增代表向前移动,rbegin()自减代表向后移动。同时统一返回string对象的字符串的最后一个字符的地址,分为普通类型和const类型,const类型的迭代器不能通过迭代器修改string对象。


d,rend()

reverse_iterator rend();const_reverse_iterator rend() const;

        反向迭代器,rend()返回对象的第一个字符的地址,rend()的自增代表向前移动,rbegin()自减代表向后移动。同时统一返回string对象的字符串的第一个字符的地址,分为普通类型和const类型,const类型的迭代器不能通过迭代器修改string对象。

他们的一般用法如下:

int main(){string s1("helosbp");string::reverse_iterator rit = s1.rbegin();while(rit != s1.rend()){cout<<*rit;++rit;}//输出pbsolehreturn 0;}


e,cbegin()

        返回一个const迭代器,迭代器指向string对象的首个字符位置。


f,cend()

        返回一个const迭代器,迭代器指向string对象的最后一个字符位置。


g,crbegin()

        返回一个const迭代器,迭代器指向string对象的首个字符位置。


h,crend()

        返回一个const迭代器,迭代器指向string对象的最后一个字符位置。


        这四种类型的迭代器一般不会主动使用,因为他们只是把前四种加上const修饰而已,但是权限不可放大,但是可以缩小,所以一般即使是const变量,也可以接受begin()返回值,这个过程称为权限缩小。

const的意义:


v,容量和长度


a,size()

size_t size() const;

        以字节为单位返回字符串的长度(length)。这是包含字符串内容的实际字节数,并不一定等于它的存储容量(capacity)。


b,lenth()

size_t length() const;

        本质和size()一致,这是早期的string设计的函数,所以string的称为string的“长度”,但是后再为了与其他的容器的接口的名字保持一致,所以有了size()函数。


c,max_size()

size_t max_size() const;

        返回string可以达到的最大长度。

        这个函数其实并没有什么实质性作用,一般的string的长度不可能接近string的最大长度,如果真是这样,那么一个string占用的内存就超过了1个G!


d,resize()

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

        重新确定size(),两个函数构成重载。将现有的string大小变成n:如果n小于现有长度,则截取n以后的串;如果n大于现有长度,扩增成n。扩增的元素指定初始化为第二个参数c,否则初始化为NULL(  ' \0 '  )。

int main(){string s1("abcde");s1.resize(10,'N');cout<<s1<<endl;return 0;}

 


e,capacity()

size_t capacity() const;

        返回当前字符串分配的存储空间大小,以字节表示。该容量不一定等于字符串长度,它可以大于或等于其长度,并允许对象在向字符串中添加新字符时进行优化操作。

        需要注意的是,此返回的容量并没有限制字符串的长度。当容量耗尽且需要更多空间时,系统会自动按需扩容(重新分配存储空间)。字符串长度的理论极限由成员max_size给出。


f,reserve()

void reserve (size_t n = 0);

        要求将string容量调整到计划的大小变化,最大长度为n个字符。如果n大于当前字符串的容量,该函数会使容器将其容量增加到n(或更大)个字符。

        如果n小于等于当前字符串的容量,都被视为缩小string容量的非硬性请求: 容器实现可以自由地进行优化,并让string的容量大于n。

        reserve()对字符串的长度(lenth)没有影响,也不能改变string的内容。

 


g,clear()

void clear();

        删除字符串中的内容,使其成为一个空字符串(长度为0个字符)。


h,empty()

bool empty() const;

        判断string是否为空。


i,shrink_to_fit()

void shrink_to_fit();

        请求字符串减少容量以适应其大小。该请求是非硬性的,容器实现可以自由地进行优化,并让字符串的容量大于其大小。

这个函数对字符串的长度(lenth)没有影响,也不能改变它的内容。


vi,元素访问


a,operator[]

char& operator[] (size_t pos);const char& operator[] (size_t pos) const;

        返回指向字符串中pos位置的字符的引用。

        这个函数是对[]的重载。目的是便于对string的串内字符的访问。

        对于返回const的引用,只可读不可写。


b,at()

char& at (size_t pos);const char& at (size_t pos) const;

        返回指向字符串中pos位置的字符的引用。

        该函数自动检查pos是否为字符串中某个字符的有效位置(即pos是否小于字符串长度),如果不是,则抛出out_of_range异常。


c,back()

char& back();const char& back() const;

        返回指向字符串最后一个字符的引用。

        此函数不能在空字符串上调用。


d,front()

char& front();const char& front() const;

        返回指向字符串第一个字符的引用。

        与成员字符串::begin返回同一个字符的迭代器不同,这个函数返回一个直接引用。

        此函数不能在空字符串上调用。


vii,修改方式


a,operator+=()
string (1)

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

在string对象后面追加另一个string对象。

int main(){string s1("aa");string s2("bbb");s1+=s2;cout<<s1<<endl; //输出aabbbreturn 0;}

c-string (2)

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

在string对象后追加C的字符串类型

int main(){string s1("aa");const char* s2 = "bbb";s1+=s2;cout<<s1<<endl; //输出aabbbreturn 0;}

character (3)

string& operator+= (char c);

在string对象后追加字符类型变量。

int main(){string s1("aa");char s2 = 'P';s1+=s2;cout<<s1<<endl; //输出aaPreturn 0;}


b,append()
string (1)

string& append (const string& str);

在string对象后面追加另一个string对象。

substring (2)

string& append (const string& str, size_t subpos, size_t sublen);

在string对象后追加另一个string对象的的子串,这个子串从下标subpos位置开始,长度为sublen。

        若不规定长度,则默认追加到结束。

c-string (3)

string& append (const char* s);

在string对象后追加C的字符串类型

buffer (4)

string& append (const char* s, size_t n);

在string对象后追加C的字符串类型,长度为前n个字符。

fill (5)

string& append (size_t n, char c);

在string对象后追加字符类型变量,个数为n个。


c,push_back()

void push_back (char c);

        将字符c添加到字符串的末尾,使其长度增加1。


d,assign()
        将一个新值赋给字符串,替换其当前内容。
string (1)

string& assign (const string& str);

一个string覆盖赋值给另一个string。

substring (2)

string& assign (const string& str, size_t subpos, size_t sublen);

一个string的子串覆盖赋值给另一个string,子串从下标subpos位置开始,长度为sublen。

c-string (3)

string& assign (const char* s);

实现C字符串覆盖赋值给string对象

buffer (4)

string& assign (const char* s, size_t n);

实现C字符串覆盖赋值 n个字符给string对象

fill (5)

string& assign (size_t n, char c);

实现字符类型覆盖赋值给string类,个数为n。


e,insert()
string (1)

string& insert (size_t pos, const string& str);

在下标n位置插入string。

substring (2)

string& insert (size_t pos, const string& str, size_t subpos, size_t sublen);

在下标n位置插入子串。

c-string (3)

string& insert (size_t pos, const char* s);

在下标n位置插入C字符串。

buffer (4)

string& insert (size_t pos, const char* s, size_t n);

在下标n位置插入C字符串的前n个字符。


f,erase()
sequence (1)

string& erase (size_t pos = 0, size_t len = npos);

删除string的串,从下标pos位置开始,长度为npos。

character (2)

iterator erase (const_iterator p);

删除迭代器指向的字符。

range (3)

iterator erase (const_iterator first, const_iterator last);

删除迭代器区间的子串。


g,replace()
string (1)

string& replace (size_t pos, size_t len, const string& str);string& replace (const_iterator i1, const_iterator i2, const string& str);

substring (2)

string& replace (size_t pos, size_t len, const string& str, size_t subpos, size_t sublen);

c-string (3)

string& replace (size_t pos, size_t len, const char* s);string& replace (const_iterator i1, const_iterator i2, const char* s);

buffer (4)

string& replace (size_t pos, size_t len, const char* s, size_t n);string& replace (const_iterator i1, const_iterator i2, const char* s, size_t n);

fill (5)

string& replace (size_t pos, size_t len, size_t n, char c);string& replace (const_iterator i1, const_iterator i2, size_t n, char c);


h,swap()

void swap (string& str);

        用str的内容交换容器的内容,str是另一个string对象。长度可能不同。

        在调用这个成员函数之后,这个对象的值是调用之前的str值,而str的值是调用之前这个对象的值。

        请注意,存在一个名称相同的非成员函数swap,它用与该成员函数类似的优化重载了该算法。


i,pop_back()

void pop_back();

        擦除字符串的最后一个字符,有效地将其长度减1。


viii,串操作


a,c_str()

const char* c_str() const noexcept;

        返回一个指向数组的指针,该数组包含一个以空字符结尾的字符序列(即C-string),表示string对象的当前值。

        这个数组包含的字符序列与string对象的值相同,另外还包含一个以空字符('\0')结尾的字符串。

        此函数的目的是在使用string时,可以调用C的有关字符串类型的函数,使C++和C有更好的兼容。


b,data()

const char* data() const;

        返回一个指向数组的指针,该数组包含的字符序列与组成string对象值的字符序列相同。

        通过data()+size()访问这个值会产生未定义的行为:不能保证返回值指向的字符序列的结尾是null字符。对于提供这种保证的函数,请参阅string::c_str。

        程序不得改变该序列中的任何字符。

        当进一步调用修改对象的其他成员函数时,返回的指针可能会失效。


c,get_allocator()

allocator_type get_allocator() const;

        返回与字符串关联的分配器对象的副本。

        String使用默认分配器<char>类型,该类型没有状态(因此,返回的值与默认构造的分配器相同)。


d,copy()

size_t copy (char* s, size_t len, size_t pos = 0) const;

        将string对象当前值的子字符串复制到s指向的数组中。这个子字符串包含从位置pos开始的len字符。

        该函数不会在复制的内容末尾添加空字符。


e,find()
string (1)

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;


f,rfind()
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;


g,find_first_of()
string (1)

size_t find_first_of (const string& str, size_t pos = 0) const;

c-string (2)

size_t find_first_of (const char* s, size_t pos = 0) const;

buffer (3)

size_t find_first_of (const char* s, size_t pos, size_t n) const;

character (4)

size_t find_first_of (char c, size_t pos = 0) const;


h,find_last_of()
string (1)

size_t find_last_of (const string& str, size_t pos = npos) const;

c-string (2)

size_t find_last_of (const char* s, size_t pos = npos) const;

buffer (3)

size_t find_last_of (const char* s, size_t pos, size_t n) const;

character (4)

size_t find_last_of (char c, size_t pos = npos) const;


i,find_first_not_of()
string (1)

size_t find_first_not_of (const string& str, size_t pos = 0) const;

c-string (2)

size_t find_first_not_of (const char* s, size_t pos = 0) const;

buffer (3)

size_t find_first_not_of (const char* s, size_t pos, size_t n) const;

character (4)

size_t find_first_not_of (char c, size_t pos = 0) const;


j,find_last_not_of()
string (1)

size_t find_last_not_of (const string& str, size_t pos = npos) const;

c-string (2)

size_t find_last_not_of (const char* s, size_t pos = npos) const;

buffer (3)

size_t find_last_not_of (const char* s, size_t pos, size_t n) const;

character (4)

size_t find_last_not_of (char c, size_t pos = npos) const;


k,substr()

string substr (size_t pos = 0, size_t len = npos) const;

        返回一个新构造的string对象,其值初始化为该对象的子字符串的副本。

        子字符串是对象的一部分,从字符位置pos开始,跨越len字符(或直到字符串末尾,以哪个先到哪个)。


l,compare()
string (1)

int compare (const string& str) const;

substrings (2)

int compare (size_t pos, size_t len, const string& str) const;int compare (size_t pos, size_t len, const string& str, size_t subpos, size_t sublen) const;

c-string (3)

int compare (const char* s) const;int compare (size_t pos, size_t len, const char* s) const;

buffer (4)

int compare (size_t pos, size_t len, const char* s, size_t n) const;


ix,成员常量


npos

static const size_t npos = -1;

        Npos是一个静态成员常量,是类型为size_t的元素的最大可能值。

        当在string的成员函数中用作len(或subblen)参数时,这个值表示“直到字符串结束”。

        作为返回值,它通常用于表示没有匹配。

        这个常数的值为-1,因为size_t是无符号整型,所以它是该类型能表示的最大值。


完~

未经作者同意禁止转载 



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。