[C++-STL之前] 剖析string类~ 介绍C++-STL
什么是 string
'\0'
结尾的一些字符的集合, 并且C标准库中也提供了一些str
系列的库函数, 但是这些库函数与字符串是分离开的, 不太符合 面向对象编程(OOP)
的思想, 而且底层空间需要用户自己管理, 稍不留神可能还会越界访问。basic_string
string
即为 以 char
为字符类型的 basic_stirng
的实例化类除 以
char
为字符类型的string
——typedef basic_string<char> u16string;
之外还有
以
char16_t
为字符类型的u16string
——typedef basic_string<char16_t> u16string;
以
char32_t
为字符类型的u32string
——typedef basic_string<char32_t> u32string;
以
wchar_t
为字符类型的wstring
——typedef basic_string<wchar_t> wstring;
四个以不同编码字符为字符类型的类, 都是 用
basic_string
这个类模板实例化出来的
string
是表示字符串的字符串类string
常用接口的介绍及使用string 常用接口的介绍及使用
string
是类模板的实例, 即它本身就是一个类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) (重点) | 拷贝构造函数 |
string (const char* s, size_t n); | 以C-string 前n 个字符, 构造 |
string (const string& str, size_t pos, size_t len = npos); | 以string类 中, pos 位置向后len 长度构造 |
使用
string
类时, 需要包含#include <iostream>
头文件 为使用方便, 可将namespace std
全部展开
-
string s1;
无参调用构造函数, 即实例化一个空对象s1
-
string s2(s);
string s3("hello world");
使用 C字符串 实例化 对象
s2
和s3
-
string s4(s2);
string s5 = s4;
调用拷贝构造函数, 实例化对象s4
和s5
-
string s6(10, 'S');
将前 10 个字节, 初始化为'S'
, 实例化对象s6
-
string s7(s, 4);
string s8("hello world", 5);
以 C字符串的前
n
个字符 实例化对象 -
string s9(s2, 2, 5);
以 字符串对象
s2
, 从pos
位置(从0开始)向后延伸n
位, 实例化对象此构造函数声明为:
string (const string& str, size_t pos, size_t len = npos);
其中
参数len
给了缺省值 npos
npos
是string
类中的静态无符号常整型值为 -1:无符号的 -1, 即为
int
类型中最大值: 4294967295参数
len
有缺省值npos
就意味着, 如果len
不传参, 就是从pos
位置延伸到字符串最后 因为实际上不会有字符串的长度 可以达到 4294967295 独占4G的内存
2. string类对象的访问及遍历操作
operator[] (重 点) | 返回pos 位置的字符 |
---|---|
迭代器iterator (重点) | begin 获取一个字符的迭代器 + end 获取最后一个字符下一个位置的迭代器 |
范围for | C++11支持更简洁的范围for 的新遍历方式 |
-
operator[]
此方法类似于 字符数组的下标访问
operator[]
是重载函数:它的返回值是, 指定位置字符的引用
这里返回 引用类型, 有两个作用:
- 返回 & 类型, 减少数据拷贝节省资源
- 返回 & 类型, 不仅可以访问指定位置的字符, 还可以修改指定位置字符, 传值返回不可
由于返回值类型为&类型, 即默认情况
可读可写
, 但不排除有只读类型的对象调用, 所以重载了一个const
修饰的函数 -
迭代器
iterator
在
string
、vector
这种实际数据内容是 一篇连续的内存空间的类中迭代器可以看作指针类型
但, 在其他
STL
类中, 不可将其简单的看作指针迭代器的比较, 最好不要用
<
>
<=
>=
, 因为在其他 类中的数据地址可能不是连续的string
中, 迭代器不仅仅有iterator
, 迭代器一共有四种:-
iterator
: 正向 可读写 迭代器 -
const_iterator
: 正向 可读 迭代器取
string
对象中字符串首字符位置, 返回给正向迭代器取
string
对象中字符串末字符的下一位置, 返回给正向迭代器const
可以很容易理解 正向, 代表 此迭代器从左向右
为正向, 即 自增移动方向为从左向右(从上面例子即可看出)
-
reverse_iterator
: 反向 可读写 迭代器 -
const_reverse_iterator
: 反向 可读 迭代器取
string
对象字符串的末字符下一位置, 返回给反向迭代器
取
string
对象中字符串首字符位置, 返回给反向迭代器
反向, 代表 此迭代器
从右向左
为正向, 即 自增移动方向为从右向左
-
-
范围
for
范围
for
方法, C++11 提出的 调用迭代器的、编写更为简洁的方法
3. string类对象的容量操作
函数名称 | 功能说明 |
---|---|
size() (重点) | 返回字符串有效字符长度 |
length() | 返回字符串有效字符长度 |
capacity() | 返回空间总大小 |
empty() (重点) | 检测字符串是否为空串, 是返回true , 否则返回false |
clear() (重点) | 清空有效字符 |
reserve(size_t n = 0) (重点) | 为字符串预留空间, 扩容量 |
resize(size_t n) (重点) | 将有效字符的个数改为n 个, 多出的空间用字符c 填充 |
max_size() | 返回字符串最大长度 |
-
size()
返回字符串 有效字符长度, 即返回 对象的size
-
length()
返回字符串 有效字符长度, 即返回 对象的size
两函数返回值相同, 即其实都返回 对象的
size
, 但是为什么有两个函数呢?因为,
string
比STL
出现的要早, 对于字符串用length
长度, 比较合适但是, 后来
STL
出现之后, 其中的类(树、链表等) 都用的size
, 所以为了统一使用string
添加了一个size
-
capacity()
返回总容量大小string
管理字符串, 空间是动态开辟的, 所以会存在有效字符大小和总空间大小, 这也就意味着 总空间满了之后, 是需要扩容的 -
empty()
检测字符串是否为空串 -
clear()
清空有效字符, 即size清零
-
reserve(size_t n = 0)
为字符串预留空间,扩容量
string
中, 字符串的维护空间是动态开辟的, 当容量满时, 是需要扩容的而执行某些操作时, 比如尾插 10000个字符, 需要频繁的扩容, 会导致效率降低
reserve
就是 防止频繁扩容降低效率时 用的, 它的作用是, 为字符串预开辟空间,可一次性开辟指定大小的空间
reserve
只能扩容, 不能缩容: -
resize(size_t n, char c)
将有效字符的个数改为n
个, 多出的空间用字符c
填充resize
存在重载函数resize(size_t n)
当使用
resize(size_t n)
不传指定字符时, 多出的位置会被初始化为0
resize
也无法缩容, 但是, 可以指定有效字符大小: -
max_size
返回字符串最大长度
4. string类对象的修改操作
函数名称 | 功能说明 |
---|---|
push_back(char c) | 在字符串后尾插字符c |
append | 在字符串后追加一个字符串 |
operator+= (重点) | 在字符串后追加字符串str |
c_str (重点) | 返回 C格式字符串 |
find (重点) | 从字符串pos 位置开始往后找字符c , 返回该字符在字符串中的位置 |
**rfind ** | 从字符串pos 位置开始往前找字符c , 返回该字符在字符串中的位置 |
substr | 在str 中从pos 位置开始, 截取n 个字符, 然后将其返回 |
insert | pos 位置插入字符串 |
erase | 指定范围删除字符 |
-
push_back(char c)
在字符串后尾插字符c
-
append
在字符串后追加一个字符串append
函数有多种重载, 即 它有多种用法: -
operator+=
在字符串后追加字符串str
这个运算符重载函数, 在
string
中 尾插用的最多, 比前面两个多得多, 因为它非常的方便 -
c_str
返回 C格式字符串, 即C语言中的指针指向的字符串c_str
非常的重要, 因为编写程序时, 可能会经常用到C语言标准库中的接口, 需要使用指针, 此时就需要c_str
发挥作用不过要注意,
c_str
的返回值是 被const
修饰的 -
find
从字符串
pos
位置开始往后找字符c
, 返回该字符在字符串中的位置find
并不仅限于找字符, 还可以找字符串: -
rfind
从字符串
pos
位置开始往前找字符c
, 返回该字符在字符串中的位置使用与
find
一致 -
substr
在
str
中从pos
位置开始, 截取n
个字符, 然后将其返回substr
将截取的字符串以string对象
的形式返回 -
insert
pos
位置插入字符串由于
insert
很可能需要挪动数据, 所以不常用 -
erase
指定范围删除字符
5. string类非成员函数
函数 | 功能说明 |
---|---|
operator+ | 尽量少用, 因为传值返回, 导致深拷贝效率低 |
operator>>(重点) | 流提取运算符重载 |
operator<<(重点) | 流插入运算符重载 |
getline(重点) | 获取一行字符串 |
relational operators(重点) | 大小比较 |
swap | 交换 两string 对象 内容 |
使用 某些类外函数时, 需要
#include <string>
-
operator+
可以在官方文档中看到,
operator+
的返回值都是传值返回, 所以一般不会使用, 还要深拷贝效率太低 -
operator>>
operator>>
主要是为了输入数据, 所以操作非常的简单但是 还有一个问题是:
当然还有其他解决办法
-
getline
获取一行字符串getline
与>>
和scanf
都不同, **getline
**只以'\n'
, 以及指定的符号
来判断接受字符结束的标志所以使用
getline
可以用来接收带空格的字符串数据甚至可以控制
获取某个指定字符之前的字符串
-
operator<<
operator<<
的作用就是直接输出 对象中字符串的内容了 -
relational operators
比较大小, 即为
>
<
==
!=
等逻辑判断运算符的重载可以实现
C类字符串
与string对象
之间的比较 -
swap
交换 两string
对象 内容
这部分内容, 都是
string类
的非成员函数其实也就是说, 操作对象的函数的定义, 不一定非要定义在类中, 也可以在类外
string
的常用接口的用法基本都介绍完了, 但是这里的内容并不是string类
中所有的接口函数string类
接口函数, 可以直接 查看官方文档。作者: 哈米d1ch 发表日期:2022 年 7 月 2 日