目录
一、标准库中的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:抱大佬的腿),新手创作,实属不易,如果满意,还请给个免费的赞,三连也不是不可以(流口水幻想)嘿!那我们下期再见喽,拜拜!