目录
一、为什么会有string?
在C语言中,字符串是以 '\0' 结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数, 但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问。在这种情况下,C++引入了string类来满足OOP。
二、对标准库中的string类的介绍
本篇博客以string - C++ Reference为纲领对string类进行说明。
1)string类是表示字符串的字符串类
2)该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。
3)string在底层实际是:basic_string模板类的别名,typedef basic_string string;
4)不能操作多字节或者变长字符的序列。
5)在使用string类时,必须包含#include头文件以及using namespace std;
三、string的常见接口说明
3.1 string的默认成员函数
3.1.1 默认构造函数
常用的构造函数如下:
第一个是构造空的string类对象,即空字符串
第二个是拷贝构造函数
第三个是用C-string来构造string类对象
不常用但需要了解的函数如下:
在讲解第一个函数之前,需要了解一下 npos,查阅文档可知:
static const size_t npos = -1;//无符号整型的-1,即最大值
好,现在可以解释上述的函数了:
第一个函数表示用 str中从pos开始的npos个字符 来构造string,当没有传递npos时,就默认到达末尾的位置(当npos的值大于str长度时也是拷贝到末尾);
第二个函数表示拷贝s的前n个字符来构造string;
第三个函数表示用n个c字符来构造string;
第四个就交由读者自行了解。
3.1.2析构函数
一般来说析构函数不需要实现,了解即可。
3.1.3赋值运算符
赋值运算符如下:
上面的函数表明了可以使用 str,s,c来为string赋值。了解之后,直接拿来使用即可
3.2迭代器介绍
常用的迭代器如下:
3.2.1 正向迭代器
begin返回的是任意容器的第一个数据的iterator,end返回的是任意容器的最后一个数据的itrator。可以顺序遍历string。
而这两个函数都有两个函数声明:iterator 可读可写;const_iterator 只可读,保证元素不能被修改。
3.2.2 反向迭代器
rbegin返回的是任意容器的最后一个数据的iterator,rend返回的是任意容器的第一个数据的前一个位置的itrator。对string进行逆序遍历。
这两个函数也有两个函数声明:原则同上。
3.3 string类对象的容量操作
最常见的操作如下:
size和length两个函数均是用来返回字符串长度的,size是为了与STL相符而优化来的;
resize是用来将有效字符的个数该成n个,多出的空间用字符c填充(省略不写的话,默认补'\0'),若减少的话,则表示删除。esize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间总大小不变;
capacity返回字符串的当前空间总大小;
reserve表示为string预留空间,不改变有效元素个数,当reserve的参数小于 string的底层空间总大小时,reserver不会改变容量大小;
clear用来清空有效字符,不改变capacity;
empty用来判断当前是否为空串,是返回true,否则返回false。
此函数是用来使容量和大小相适应的,但不建议使用,因为释放内存空间时不能分段释放,因此这个函数会优先申请一块合适的空间来存放数据,但是时间消耗较大。
3.4 string类对象的访问及遍历操作
对于string的遍历有4种方式,接下来将一一介绍:
3.4.1 operate[ ]
字符串实质上也是对字符数组的封装,因此也可重载[ ]来支持字符串的遍历。
3.4.2 begin + end
这两个迭代器实现了string类对象的正向遍历。
3.4.3 rbegin + rend
这两个迭代器实现了string类对象的反向遍历。
3.4.4 范围for循环
范围for是C++11引入的操作,他大大的方便了我们对数组等的遍历。
具体的代码实现:
void Teststring()
{
string s("hello Bit");
// 3种遍历方式:
// 需要注意的以下三种方式除了遍历string对象,还可以遍历是修改string中的字符,
// 另外以下三种方式对于string而言,第一种使用最多
// 1. for+operator[]
for (size_t i = 0; i < s.size(); ++i)
cout << s[i] << endl;
// 2.迭代器
string::iterator it = s.begin();
while (it != s.end())
{
cout << *it << endl;
++it;
}
// string::reverse_iterator rit = s.rbegin();
// C++11之后,直接使用auto定义迭代器,让编译器推到迭代器的类型
auto rit = s.rbegin();
while (rit != s.rend())
cout << *rit << endl;
// 3.范围for
for (auto ch : s)
cout << ch << endl;
}
3.5 string类对象的修改操作
对类对象的插入操作:
append表示在末尾追加字符串,push——back表示插入字符,但最常见的是+=。
若是对首元素或者中间元素的插入和删除操作,时间复杂度为O(N),时间消耗很大,不是特别建议使用。
3.6 string类对象的其他接口
find是用来从pos位置开始查找目标字符串或字符的下标,refind是用来逆序查找。其他接口了解即可。
该函数用来截取从pos位置开始的数据,默认到结束位置为止。
该函数用来将C++的字符串转化为C语言的字符数组。
流插入与流提取重载了<<和>>,来操作字符串的输入与输出。
getline则是读入一串字符。
3.6 vs和g++下string结构的说明