目录
1、了解string
2、string相关函数
3、相关函数的使用
①构造函数
②赋值
③>>,<<
④operator[]
⑤size
⑥iterator(迭代器)
⑦push_back
⑧append
⑨+=
⑩capacity
⑪reserve
⑫resize
⑬insert
⑭erase
⑮c_str
⑯find
⑰substr
⑱getline
⑲to_string
⑳stoi/stod
STL是C++标准库的重要组成部分,是一个包罗数据结构与算法的软件框架
list/vector/string/deque都属于STL中的容器
下面就重点介绍string的用法
1、了解string
①string是表示字符串的字符串类
②string类是使用char作为它的字符类型
2、string相关函数
3、相关函数的使用
①构造函数
如图:
可以使用无参构造,也可以使用上图的第4中方式,一个常量字符串构造
这两个是最常用的,要注意不管是s1还是s2,它们的末尾都有一个/0
也可以进行拷贝构造:
还有可以拷贝一部分,即这个构造函数
意思是拷贝str,从pos位置拷贝到len位置,len位置的缺省参数npos
就是说npos是整型的最大值,即一个非常大的数
s2想拷贝从s1的第6个位置拷贝5个字符
这里还有一个注意事项,就是如果第三个参数大于pos后面的字符长度,那么也就是从pos位置拷贝完所有字符就结束
从第6个位置后面只有5个字符,那么我即使是输入的是10,也只打印剩下的5个字符
所以给npos这个缺省参数,就是用户如果没给打印几个字符,那么则从pos位置开始有多少就拷贝多少
②赋值
分别对应三种赋值重载
③>>,<<
并且重载了>>和<<运算符,就可以直接cin/cout了
即:
④operator[]
重载的[]可以让string类像数组一样去访问
普通对象就调用第一个,const对象就调用第二个
这里的返回值是引用,所以就可以修改返回值,也有减少拷贝的作用
operator[]也会检查越界 ,因为里面实现时用了assert,程序直接终止
还有一个at和[]用法基本一致,但是at越界的话是抛异常,不会像[]直接程序终止
⑤size
我们可以用size来进行循环中的判断,s1.size()就是s1字符串的长度
length和size用法也相同,但是由于string创建比较早,所以取名为length,而且也为了和后面要学习的其他容器保持一致,后面学习的树之类的再用length就不合适了,所以有了size,因此几乎不用length,都用size
⑥iterator(迭代器)
迭代器是一个像指针一样的东西,可能是指针也可能不是指针,但是用法像指针一样
迭代器的使用是以下的方式:
it是自己取的名字,叫什么都行
迭代器都是在内部定义的,所以属于这个类域,因此是string::iterator调用
s.begin()和s.end()就相当于:
所以每次*it然后++it就可以遍历出s1的内容
迭代器都给的是[),即左闭右开的区间,所以end()就是最后一个元素的下一个位置,所以这样it一直++到end(),就可以遍历完
看下图可知,begin和end返回的也是iterator
但是在string和vector中,我们不常用迭代器,一般用[],迭代器效率也比较低,[]更方便些也更快
但是到了list/map/set就不能用[]了,因为这些容器并不是连续的物理空间存储的,只能用迭代器访问,所以迭代器还是非常重要的,需要熟练掌握
iterator是所有容器的通用访问方式,用法是类似的,也就是你只要会用一个容器的迭代器,那你也自然就会用其他容器的迭代器了
学习了迭代器,这时候就需要提到范围for了,因为范围for使用起来方便,可以自动迭代,自动判断结束,而学习完迭代器我们就需要知道,范围for的底层其实就是用迭代器实现的
这两种方式都可以进行遍历,这里的iterator是正向迭代器
上面的iterator是正向迭代器,那既然有正向迭代器,自然也有反向迭代器
反向迭代器是reverse_iterator,里面用到的就是rbegin和rend了
正向迭代器是正着遍历,所以反向迭代器就是反着遍历了
其中rbegin和rend的大概位置如下:
rend是第一个位置的前一个位置
rit++是朝左边动的
⑦push_back
push_back是插入一个字符
⑧append
push_back是插入一个字符串
⑨+=
上面的push_back和append能用,但是在string类中,重载了+=运算符,比上面两种方便很多
+=一个字符,+=一个字符串都很好用
⑩capacity
capacity是用于返回现阶段的容量
⑪reserve
reserve是用于提前开空间,避免扩容造成的损耗
s1.reserve(50)即提前开空间,有效的减少扩容造成的损耗
⑫resize
resize是用于提前开空间加初始化
比如s1.resize(50)则默认开的50个空间都初始化为0
如果想初始化为其他的,比如说初始化为a,则s1.resize(50,'a')即可
⑬insert
insert是指定位置插入字符或字符串
下面介绍最常用的一种
意思就是从0位置插入一个字符串“hello ”
⑭erase
erase是用于删除字符或字符串
常用的是第一个,给了两个缺省参数,意思是从pos位置删除len个字符
其中npos是一个非常大的数,也就是不给的话,就默认删除完剩下的字符
s1.erase(5)指从第5个字符开始,剩下的删完
s1.erase()指全部删完
但是这里说明一点,insert和erase少用,因为效果并不理想
⑮c_str
c_str是用于将字符串转化为c类型的字符串
而c类型的字符串的特点就是遇到\0就终止
而C++的字符串是按照size终止的,即打印完size个
c类型的字符串+='\0'打印时就终止了
C++则打印完所有的字符菜才终止
⑯find
find是用于查找字符或字符串
这里的返回值是size_t,也就是无符号整型
find当然会出现找到和没有找到两种情况,规定如果找到了就返回找到的第一个字符的位置,如果没有找到就返回npos,即整型的最大值
所以要用if语句判断返回值是否等于string::npos
也有一个rfind,这个是返回找到的最后一个字符的位置
主要用于打印最后一个后缀的情况,如:
我们只想要后缀.com,如果用find不符合要求
如上图,用rfind就能很好地解决
⑰substr
substr是取字符串的一部分
如下图,substr就是取出从pos开始的len个字符,也给了两个缺省值,不给pos就是从0开始取,不给len就是全部去完为止
substr经常与find结合起来使用
⑱getline
getline是用于输入字符串中有空格的情况
我们用的cin,如果输入两个字符串,输入完一个字符串空格或换行都可以完成两个字符串的分割
但是有一种情况如果要输入一个字符串中间有空格,用cin输入就会出现这种情况:
我们本来想要hello world,但是由于这个字符串中有空格,编译器误以为空格是多个字符串之间的分割,所以打印到空格就结束了,最终只打印了空格前的字符串,不满足要求
用getline就可以完美解决这个问题了
第一个用法是,在第三个参数中可以给一字符用于判断字符串结束标志
第二个用红框住的是常用用法,如下所示:
⑲to_string
to_string是转化为字符的函数,常见类型都可以转化
⑳stoi/stod
stoi/stod是字符转化为其他类型,同样常见的类型都可以转化