什么是STL?
STL(standard template libaray )标准模板库
是C++标准库的重要组成部分 不仅是一个可以复用的组件库 更是一个包罗数据结构算法的软件框架
以下是STL的六大组件 大概了解一下以后会详细介绍。
STL六大组件:
1.仿函数
如:greater less
2.算法
如:find swap reverse sort merge
3.迭代器
如:iterator const_iterator reverse_iterator const_reverse_iterator
4.空间配置器
如:allocator
5.容器
如:string vector list deque map set multimap
mutilset
6.配接器
如:stack queue priority_queue
什么是string?
- string是表示字符串的字符串类
- 该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。
- string在底层实际是:basic_string 模板类的别名,typedef basic_string<char, char_traits, allocator> string;
- 不能操作多字节或者变长字符的序列。
在使用string类时必须包含头文件 <string> 以及using namespace std;
接下来主要讲一些 string 类里所包含的一些常用的方法和函数 例如 构造 赋值 删除 插入、连接字符 获取字符 查询等等
一、string的常见构造方法
1. string (); 构造一个空的string对象 即空的字符串
例: string s1;
2. string(const char* s);用C-string来构造string类对象
例 :string s2("hello world");
3. string(const string&s); 用一个string类对象拷贝构造另一个string类对象
例:string s1(s2);
4. string(size_t n, char c); 用n个字符c来构造string类对象
例:string s1(10,'a');
5. string(const string&s, size_t n);用s中的前n个字符构造新的string类对象
例:string s2(s1,5);
二、string类对象的空间容量的操作
1. size_t size() const 返回string对象的有效字符的size 也就是长度
例:string s1("hello world") cout<<s1.size();<<endl;
与其同样可以计算string类对象的还有
2. size_t length() const 也是返回字符串有效字符长度
例:string s1("hello world"); cout<<s1.length()<<endl;
size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一 致,一般情况下基本都是用size()。
3. size_t capacity ( ) const 返回空间的总大小
例:string s1("hello world"); cout<<s1.capacity()<<endl;
这里可以看到 一个string类的对象的空间大小 并不是和字符串有效长度的同等大小的,那么string类对象在底层的空间到底是如何分配的呢?接下来看一段代码:
#include<iostream>
#include<string>
#include<stdlib.h>
using namespace std;
int main()
{
string s1("hello world");
int i=0;
for(i=0; i<50; i++)
{
s1+='a';//尾插一个 char类型的字符'a' 观察有效字符串和容量的变化
cout<<"s1.size()="<<s1.size();
cout<<" ";
cout<<"s1.capacity()="<<s1.capacity()<<endl;
}
system("pause");
return 0;
}
可以发现其容量当不够时就会扩容,是由底层实现的,暂时不讲其原理,可以发现容量增长规律 大概是呈1.5倍增长。
4. bool empty ( ) const 检测字符串释放为空串,是返回true,否则返回false。
例:
string s1;
string s2("a");
cout<<s1.empty()<<endl;
cout<<s2.empty()<<endl;
可以看到 s1 是一个空的字符串 因此返回1 即为true 而s2不是一个空字符串因此返回false 返回 0
5. void clear() 清空有效字符
例: string s1("hello world"); s1.clear(); cout<<s1<<endl;
注意:观察清空后其有效字符串、以及容量的变化:
#include<iostream>
#include<string>
#include<stdlib.h>
using namespace std;
int main()
{
string s1("hello world");
s1.clear();
if(s1.empty())
{
cout<<"s1=NULL"<<endl;
}
else
{
cout<<s1<<endl;
}
cout<<"s1.size()"<<s1.size()<<endl;
cout<<"s1.capacity()="<<s1.capacity()<<endl;
system("pause");
return 0;
}
观察可以发现 clear 只是清空了string 对象的内容 但并不是释放了这块地址空间 容量还是保持不变的。
6. void resize ( size_t n, char c ) 将有效字符的个数修改成n个,并且多出的空间用字符c填充。
7.void resize ( size_t n ) 将有效字符的个数改成n个,多出的空间用0填充
例:string s1 ("hello"); s1.resize(10,'a'); cout<<s1<<endl;
例:string s1("hello "); s1.resize(3); cout<<s1<<endl;
#include<iostream>
#include<string>
#include<stdlib.h>
using namespace std;
int main()
{
string s1("hello ");
s1.resize(10);
cout<<s1<<endl;
s1.resize(15,'a');
cout<<s1<<endl;;
s1.resize(4);
cout<<s1<<endl;
system("pause");
return 0;
}
可以看到 resize 两个参数的区别就是 当只有一个是用0替代多余出来的空间 而而另一个是用 一个 char c 字符来替代。
注意:resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大 小,如果是将元素个数减少,底层空间总大小不变
8. void reserve ( size_t res_arg=0 ) 为字符串预留空间
例: string s1("hello"); s1.reserve(100); cout<<s1.capacity()<<endl;
这样做的目的是 当大概知道所需要的空间大小时 可以为string 对象预留一定的空间 减少底层扩容时所付出的代价:
代码演示:
#include<iostream>
#include<string>
#include<stdlib.h>
using namespace std;
int main()
{
int i;
string s1("hello ");
s1.reserve(100);
for(i=0; i<100; i++)
{
s1+='c';
cout<<"s1.size():"<<s1.size();
cout<<" ";
cout<<"s1.capacity:"<<s1.capacity()<<endl;
}
system("pause");
return 0;
}
注意:reserve(size_t res_arg=0):为string预留空间,不改变有效元素个数,当reserve的参数小于 string的底层空间总大小时,reserver不会改变容量大小
三、string类对象的访问操作
即使用 " [ ] " 对string 类对象进行访问和操作 但要区分 是否是const 类型的string 类对象 以及他们之间的调用关系.
char& operator[] ( size_t pos ) 返回pos位置的字符,const string类对象调用
const char& operator[] ( size_t pos ) const 返回pos位置的字符,const string类对象调用
例:
int main()
{
string s1("hello world");
const string s2("change world");
s1[0]='H';//s2[0]='C' 这里报错 显示表达式是必须可修改的左值
//使用 方括号进行对string类对象访问
cout<<s1[0]<<" "<<s2[0]<<endl;
system("pause");
return 0;
}
四、string类对象的修改操作
1. void push_back(char c) 在字符串后尾插字符c
另外与之对应的还有pop_back(char c) 功能是尾删一个字符;
例:string s1; s1.push_back('h');
int main()
{
string s1;
s1.push_back('h');
s1.push_back('e');
s1.push_back('l');
s1.push_back('l');
s1.push_back('o');
cout<<s1<<endl;
s1.pop_back();//尾删一个数据
s1.pop_back();
cout<<s1<<endl;
system("pause");
return 0;
}
2. string& append (const char* s); 在字符串后追加一个字符串
3. string& operator+=(const string& str)在字符串后追加字符串str
4. string& operator+=(const char* s) 在字符串后追加C个数字符串
5. string& operator+=(char c) 在字符串后追加字符c
例如:代码
int main()
{
string s1;
//2. string& append (const char* s); 在字符串后追加一个字符串
s1.append("hello ");
cout<<s1<<endl;
//3. string& operator+=(const string& str)在字符串后追加字符串str
string s2("wo");
s1+=s2;
cout<<s2<<endl;
//4. string& operator+=(const char* s) 在字符串后追加C个数字符串
s1+="rl";
cout<<s1<<endl;
//5. string& operator+=(char c) 在字符串后追加字符c
s1+='d';
cout<<s1<<endl;
system("pause");
return 0;
}
运行结果:
注意: 在string尾部追加字符时,s.push_back ( c ) / s.append(1, c) / s += 'c’三种的实现方式差不多,一般 情况下string类的+=操作用的比较多,+=操作不仅可以连接单个字符,还可以连接字符串。
6. const char* c_str( )const 返回C格式字符串
例:以C语言的方式打印字符串
7.size_t find (char c, size_t pos = 0)const从字符串pos位置开始往后找字符c,返回该字符在 字符串中的位置
8.size_t rfind(char c, size_t pos = npos)从字符串pos位置开始往前找字符c,返回该字符在 字符串中的位置
代码演示:
int main()
{
int tmp1,tmp2,tmp3;
string s1("123456789");
tmp1=s1.find('4',0);
cout<<tmp1<<endl;
tmp2=s1.rfind('4',8);
cout<<tmp2<<endl;
tmp3=s1.find('a',2);//当找不到时会返回-1
cout<<tmp3<<endl;
system("pause");
return 0;
}
9.string substr(size_t pos = 0, size_t n = npos)const在str中从pos位置开始,截取n个字符,然后将其 返回
例如:
以上便是在构建string 类对象且对string 类对象进行一些访问、修改、查找等操作的比较常见的接口,另外还有很多的接口如下:
#include<iostream>
#include<string>
#include<stdlib.h>
using namespace std;
int main()
{
int i=2;
string s1("hello world");
string s2("haha");
cout<<s1.front()<<endl;//返回第一个字符
cout<<s1.back()<<endl;//返回最后一个字符
swap(s1,s2);//交换两个字符或字符串
cout<<s1<<endl;
cout<<s2<<endl;
cout<<s1.compare(s2)<<endl;//比较两个字符串长度的大小
string s3(s2,0,4); //拷贝构造 用S2 的字符串中
//pos的位置的开始后的n个字符串内容来构造 s3
cout<<s3<<endl;
cout<<s1.at(i)<<endl;//访问 i处的字符
string s4;
getline(cin,s4);// cin 以 空格 分割输入的字符串
//而 getline 以换行符来分割 获取一行输入的字符
cout<<s4<<endl;
s1.assign("change world");//赋予新值
cout<<s1<<endl;
system("pause");
return 0;
}
结果如下:
还有一些string类的非成员函数 以及深浅拷贝问题 ,string的模拟实现会在以后的博客继续整理;
来源:CSDN
作者:起个名字好难丫
链接:https://blog.csdn.net/weixin_42307601/article/details/104032626