目录
一、标准库中的string类
1. string类
2. string类的常用接口说明
2.1 string类对象的常见构造
2.2 string类对象的容量操作
2.3 string类对象的访问及遍历操作
2.4 string类对象的修改操作
2.5 string类非成员函数
总结
前言
C语言中,字符串是以 '\0' 结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户自己管理,稍不留神还可能会越界访问。
所以C++在早期,实现STL前,便实现了stirng类,方便使用,但是实现过早也有弊端,string与STL其他容器相较而言有些许不规范和接口冗余。
本节我们初步学习string类中一些接口的使用,具体细节可以在https://legacy.cplusplus.com/reference/string/string/查阅
一、标准库中的string类
1. string类
1. 字符串是表示字符序列的类
2. 标准的字符串类提供了对此类对象的支持,其接口类似于标准字符容器的接口,但添加了专门用于操作单字节字符字符串的设计特性。3. string 类是使用 char( 即作为它的字符类型,使用它的默认 char_traits 和分配器类型 ( 关于模板的更多信息,请参阅basic_string) 。4. string 类是 basic_string 模板类的一个实例,它使用 char 来实例化 basic_string 模板类,并用 char_traits和allocator 作为 basic_string 的默认参数 ( 根于更多的模板信息请参 basic_string) 。5. 注意,这个类独立于所使用的编码来处理字节: 如果用来处理多字节或变长字符 ( 如 UTF-8) 的序列,这个类的所有成员( 如长度或大小 ) 以及它的迭代器,将仍然按照字节 ( 而不是实际编码的字符 ) 来操作。
2. string类的常用接口说明
2.1 string类对象的常见构造
(constructor)函数名称
|
功能说明
|
string() (重点)
|
构造空的string类对象,即空字符串
|
string(const char* s) (重点)
|
用C-string来构造string类对象
|
string(size_t n, char c)
|
string类对象中包含n个字符c
|
string(const string&s) (重点)
| 拷贝构造函数 |
2.2 string类对象的容量操作
函数名称
| 功能说明 |
size
(重点)
|
返回字符串有效字符长度
|
length
|
返回字符串有效字符长度
|
capacity
|
返回空间总大小
|
empty
(重点)
|
检测字符串释放为空串,是返回
true
,否则返回
false
|
clear
(重点)
|
清空有效字符
|
reserve
(重点)
|
为字符串预留空间
|
resize (重点)
|
将有效字符的个数该成
n
个,多出的空间用字符
c
填充
|
1. 对于reserve(),如果申请的空间大于capacity,那么就扩容,如果申请的空间小于capacity,根据编译器自动优化,即,如果有数据,那么就不缩减容量;如果此前使用了clear() ,没有数据,编译器认为就可以缩减容量。
翻译:
- 如果 n 大于当前字符串容量,则该函数会导致容器将其容量增加到 n 个字符(或更大)。
- 在所有其他情况下,收缩字符串容量被视为非约束性请求:容器实现可以自由优化,否则,字符串的容量大于 n。
2. 对于resize(),它不仅开空间,而且会初始化填数据,如果不给值,默认填充’ \0'
翻译:
- 如果 n 小于当前字符串长度,则当前值将缩短为其第一个 n 个字符,删除第 n 个字符以外的字符,size改变,capacity不变。
- 如果 n 大于当前字符串长度,则通过在末尾插入所需数量的字符以达到 n 大小来扩展当前内容。如果指定了 c,则新元素初始化为 c 的副本,否则,它们是值初始化字符(空字符)。
例:
int main() { string s1("hello world"); //开空间 s1.reserve(100); cout << s1.size() << endl; cout << s1.capacity() << endl; //开空间+初始化填值 s1.resize(100); cout << s1.size() << endl; cout << s1.capacity() << endl; return 0; }
打印 11 111 100 111
总结:一般情况,容量是不会缩小的,因为缩小的代价不小,因为如果单纯的只释放一部分空间,free是做不到的,只有在 clear() 后的特殊情况,再缩减,容量才会改变。
在C++11中,又提供了一个接口 shrink_to_fit() ,可以支持缩减容量直至等于size大小
2.3 string类对象的访问及遍历操作
函数名称
|
功能说明
|
operator[ ]
(重点)
|
返回
pos
位置的字符,
const string
类对象调用
|
begin
+
end
|
begin
获取一个字符的迭代器
+
end
获取最后一个字符下一个位置的迭
代器
|
rbegin
+
rend
|
begin
获取一个字符的迭代器
+
end
获取最后一个字符下一个位置的迭
代器
|
范围
for
|
C++11
支持更简洁的范围
for
的新遍历方式
|
[ ]会进行断言错误,at()会进行抛异常
int main()
{
string s1("hello world");
char s2[] = "hello world";
//一个是类,一个是数组
s1[1]++;//s1.operator[](1),类的成员函数
s2[1]++;//*(s2 + 1),地址解引用
return 0;
}
- iterator是像指针一样的类型,有可能是指针,有可能不是指针。
- iterator迭代器提供了一种统一的方式进行访问和修改容器的数据,算法可以通过迭代器去处理容器中的数据
- [ ] 可读可写,当对象被const修饰,那么就不可修改值
- beign()迭代器指向第一个元素、end()迭代器指向最后一个元素的下一个位置,左闭右开,这里end()指向的是 ‘\0'
- 对于倒序遍历,rbegin()指向最后一个数据,rend()指向第一个数据的前一个位置,使用迭代器时要用——reverse_iterator
string::reverse_iterator rit = s.rbegin();
- 对于const对象,不能用普通的迭代器,这样相当于权限放大,因为可以迭代器可以修改值,所以此时的迭代器会有另一种形式——const_iterator;同理,对于反向迭代器,如果对象被const修饰,那么迭代器应写为——const_reverse_iterator
void Func(const string& s) { string::const_iterator it = s.begin(); while (it != s.end()) { cout << *it << ' '; it++; } cout << endl; }
2.4 string类对象的修改操作
函数名称
|
功能说明
|
push_back
|
在字符串后尾插字符
c
|
append
|
在字符串后追加一个字符串
|
operator+=
(
重点
)
|
在字符串后追加字符串
str
|
c_str
(
重点
)
|
返回
C
格式字符串
|
find
+
npos
(
重点
)
|
从字符串
pos
位置开始往后找字符
c
,返回该字符在字符串中的位置
|
rfind
|
从字符串
pos
位置开始往前找字符
c
,返回该字符在字符串中的位置
|
substr
|
在
str
中从
pos
位置开始,截取
n
个字符,然后将其返回
|
npos == -1,但类型是size_t,无符号数,-1表示最大值
从pos开始,插入从subpos开始,长度为 sublen 的 string类字符串或C语言字符串,sublen不写,会默认从subpos开始全插入,sublen填写-1也可以,因为是size_t类型,-1表示最大值
由于string是由顺序表实现的,中间的插入删除效率很低,所以不到万不得已,尽量不用
c_str是返回一个c语言类型的数组指针,方便使用c的一些接口函数
2.5 string类非成员函数
函数 | 功能说明 |
operator+
| 尽量少用,因为传值返回,导致深拷贝效率低 |
operator>>
(重点)
| 输入运算符重载 |
operator<<
(重点)
| 输出运算符重载 |
getline
(重点)
| 获取一行字符串 |
relational operators
(重点)
| 大小比较 |
将其他类型转为string类型
将string类型转为整形
总结
本节初步了解string类的使用方法,由于string在C++早期便有了,所以它的接口有很多人吐槽冗余,由于它是由顺序表实现,插入删除在底层的实现效率不高,了解部分的接口,方便使用即可。具体更多的接口概念与定义在https://legacy.cplusplus.com/reference/string/string/网站内查询。
下节课,我们将模拟实现string
最后,如果小帅的本文哪里有错误,还请大家指出,请在评论区留言(ps:抱大佬的腿),新手创作,实属不易,如果满意,还请给个免费的赞,三连也不是不可以(流口水幻想)嘿!那我们下期再见喽,拜拜!