C++string使用
Posted Suk-god
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++string使用相关的知识,希望对你有一定的参考价值。
文章目录
1、 为什么要学习string类
1、C语言中,字符串是以’\\0
’结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问
2、在OJ中,有关字符串的题目基本以string类的形式出现,而且在常规工作中,为了简单、方便、快捷,基本都使用string类,很少有人去使用C库中的字符串操作函数
2、标准库中的string类
2.1了解string类
- 字符串是表示字符序列的类
- 标准的字符串类提供了对此类对象的支持,其接口类似于标准字符容器的接口,但添加了专门用于操作单字节字符字符串的设计特性。
- string类是使用char(即作为它的字符类型,使用它的默认char_traits和分配器类型)
- string类是basic_string模板类的一个实例,它使用char来实例化basic_string模板类,并用char_traits和allocator作为basic_string的默认参数
- 注意,这个类独立于所使用的编码来处理字节:如果用来处理多字节或变长字符(如UTF-8)的序列,这个类的所有成员(如长度或大小)以及它的迭代器,将仍然按照字节(而不是实际编码的字符)来操作。
总结:
- string是表示字符串的字符串类
- 该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。
- string在底层实际是:basic_string模板类的别名,typedef basic_string<char, char_traits, allocator> string;
- 不能操作多字节或者变长字符的序列。
在使用string类时,必须包含#include<string>
头文件以及using namespace std
2.2string类常用的接口
申明:以下的所有Windows平台测试均在VS2013环境下进行,期间也会有部分功能在Linux平台下测试
2.2.1 构造和析构相关
- (constructor)—构造
(1)string()
默认构造函数,得到的是一个长度为0的空串
(2)string(const string& str)
这是一个 拷贝构造函数,用已经存在的字符串str拷贝构造新的字符串
具体使用方式如下:
(3)sting(const string& str,size_t pos,size_t len = npos)
功能:使用字符串str的从pos下标开始,长度为len这一部分字符串来构造新的字符串(len是一个缺省参数,默认值为npos,如果不给定,默认到字符串str的末尾)
功能演示
(4)string(const char* s)
使用C语言中的字符串来构造新的对string对象
(5)string(const char* s,size_t n);
使用C语言中的字符串s中的前n个字符来构造string对象
(6)string(size_t n,char c)
使用n个字符c来构造string对象
(7)template<class InputIterator>
string(InputIterator first,InputIterator last)
- (destructor)—析构
~string();
每个对象在生命周期结束时会自动调用该析构函数
- operator=—赋值
(1)string& operator= (const string& str)
;
(2)string& operator= (const char* s)
;
(3)string& operator= (char c)
;
2.2.2 迭代器
暂时理解—是一个类似于指针的玩意儿
2. begin() && end()
iterator begin() | const_iterator begin() const
;
iterator end() | const_iterator end() const
;
3. rbegin() && rend()
reverse_iterator rbegin() | const_reverse_iterator rbegin() const
;
reverse_iterator rend() | const_reverse_iterator rend() const
;
画图解释:
2.2.3 容量相关
size_t size() const
;size_t length() const
;
size() 和length()功能完全一致,都是获取字符串的有效长度
展示:
疑问:为什么string要提供两个功能完全一致的方法size()和length()呢?
原因: length是因为沿用C语言的习惯而保留下来的,string类最初只有length,引入STL之后,为了兼容又加入了size,它是作为STL容器的属性存在的,便于符合STL的接口规则,以便用于STL的算法
-
size_t capacity() const
;
获取string对象在底层维护的顺序表的容量
-
void resize(size_t newsize);
|void resize(size_t newsize,char c)
;
resize—将string对象现有的有效元素个数更新为newsize个
注意:newsize的值可以大于原来有效元素的个数,也可以小于。因此,我们在使用resize的时候要注意区分。具体情况见下图:
下面我们通过代码验证上述的每个情况:
①验证newsize<= oldsize
②验证newsize > oldsize && newsize <= capacity
③验证newsize > olssize && newsize > capacity
-
void reverse(size_t newcapacity = 0)
;
作用:扩容,只改变容量,不会修改有效元素的个数
假设string中原来的容量为oldcapacity,现在的参数为newcapacity
验证:
(1)newcapacity <= oldcapacity
①newcapacity <= oldcapacity && oldcapacity <= 15
②newcapacity <= oldcapacity && oldcapacity > 15 && newcapacity >15
③newcapacity <= oldcapacity && oldcapacity > 15 && newcapacity <=15
为什么在newcapacity<=15 && oldcapacity > 15的情况下,缩小容量会变成15?
原因分析:在string类的内部除了维护顺序表必须的三个成员以外,还有一个char array[BUF_SIZE],该数组的大小为16。具体如下图
(2)newcapacity > oldcapacity
会进行扩容,主要执行以下步骤:
开辟新空间—>拷贝元素---->释放旧空间—>返回新空间
验证string内部扩容的方式~
Ⅰ在Windows平台下使用VS2013验证
Ⅱ在Linux平台下验证
-
void clear()
;
清空有效元素,不改变空间大小
2.2.4 元素访问 && 元素遍历
元素访问
使用[]和at两类方法访问元素时,效果一样,只是针对于异常情况的处理方式不一样。具体区别如下:
(1)operator[]
char& operator[](size_t pos)
| const char& operator[](size_t pos)const
在访问越界的时候,会触发assert断言,直接终止程序
(2)at
char& at(size_t pos)
| const char& at(size_t pos) const
在访问越界的时候,会抛出异常,用户可以对其进行捕获
总结operator[] 与at:
(3)front----C++11
char& front()
; | const char front()const
C++11中引入的新方法,获取string的第一个字符
(4)back----C++11
char& back()
; | const char back()const
C++11中引入的新方法,获取string的最后一个字符
疑问:为什么这些元素访问类的函数,都会提供const和非const两份代码呢?
这个想要搞清楚,首先要明白const修饰成员函数后有哪些特性!(深入了解点这里)由于const对象不能调用非const的成员函数,所以必须提供两份代码。不然被const修饰对象就无法调用该方法,那也就意味着无法访问string的pos处的元素,这显然是不合理的!因此,对于这种元素访问类型的方法,需要提供两份代码!
元素遍历
(1)for循环+[]访问
(2)迭代器
(3)范围for
这个比较简单,直接看代码
int main()
string str("hello");
//for+[]
for (int i = 0; i < str.size(); i++)
cout << str[i];
cout << endl;
//迭代器
string::iterator it = str.begin();
while (it != str.end())
cout << *it;
it++;
cout << endl;
//范围for
for (auto e : str)
cout << e;
cout << endl;
return 0;
2.2.5 修改相关
- operator+=
string& operator+=(const string& str)
;—末尾追加string
string& operator+=(const char* s)
;----末尾追加C中的字符串
string& operator+=(const char c)
;—末尾追加字符
- append
①string& append(const string& str)
;
功能:末尾追加一个str
②string& append(const string& str,size_t subpos,size_t sublen);
功能:将str从subpos开始,长度为sublen的子串追加到调用者的末尾
③string& append(const char* s);
功能:在末尾追加一个C中的字符串
④string& append(const char* s,size_t n);
功能:在末尾追加字符串s从0号位置开始,长度为n的子串
⑤string& append(size_t n,char c);
功能:在末尾追加n个char类型的元素c
⑥template<calss IputIterator>
string& append(InputIterator first,InputIterator last)
;
功能:将迭代器first–last区间内的内容追加到字符串的末尾
- push_back
void push_back(char c)
;
功能:末尾追加一个字符c
- insert
①string& insert(size_t pos,const string& str);
功能:在pos处,插入字符串str
②string& insert(size_t pos,const string& str,size_t subpos,size_t sublen);
功能:在pos处插入str从subpos开始,长度为sublen的子串
③string& insert(size_t pos,const char* s);
功能:在pos处插入C中的字符串s
④string& insert(size_t pos,const char* s,size_t n);
功能:在pos处插入字符串s的前n个字符
⑤string& insert(size_t pos,size_t n,char c);
void insert(iterator p,size_t n,char c)
;
功能:在pos或者p处插入n个字符c
- erase
①string& erase(size_t pos = 0,size_t len = npos);
功能:删除从pos开始,长度为len的子串。
注意:pos和len均为缺省参数,默认删除整个字符串
②iterator erase(iterator p);
功能:删除p位置的元素,返回下一个元素的位置
注意:在删除字符串的最后一个位置时,返回值是非法的,无法再次被使用
③iterator erase(iterator first,iterator last)
;
删除区间first–last之间的元素
- swap
void swap(string& str)
;
功能:交换两个string类型的对象,string::swap效率比全局的swap要高,在交换字符串的时候强烈建议使用string::swap
2.2.6 其他
- c_str
const char* c_str() const
;
以C语言的方式返回字符串string
- find
①size_t find(const string& str,size_t pos = 0)const;
功能:在目标字符串中查找str字符串出现的位置,默认从头开始查找。找到返回str首个字符在目标字符串中的位置,找不到返回npos
②size_t find(const char* s,size_t pos = 0)const
;
功能与上一个一致,唯一区别是这个查询的是C中的字符串
③size_t find(const char* s,size_t pos,size_t n)const
;
功能:查询C中字符串的前n个字符
④size_t find(char c,size_t pos=0)const
;
功能:查询字符c的位置,,哦人从0下标开始查询 - rfind
功能与find类似,只不过是从字符串的末尾向起始位置查找
- find_first_of
与find类似,只不过是查找第一次出现的某一个字符或字符串
接口如下:
①
size_t find_first_of(const string& str,size_t pos=0)const;
找第1次出现string str的位置,默认从头开始查找
②
size_t find_first_of(const char*s,size_t pos=0)const;
找第1次出现C语言字符串s的位置,默认从头开始查找
③
size_tfind_first_of(const char* s,size_t pos,size_t n)const;
找第1次出现C语言字符串s从pos开始,长度为n的子串的位置,
④
size_t find_first_of(char c,size_tpos=0)const;
找第1次出现字符c的位置,默认从起始位置开始查找
- find_last_of
与rfind类似,只不过是查找第一次出现的某一个字符或字符串
接口如下:
①
size_t find_last_of(const string& str,size_t pos=npos)const;
找第1次出现string str的位置,默认从末尾开始查找
②
size_t find_last_of(const char*s,size_t pos=npos)const;
找第1次出现C语言字符串s的位置,默认从末尾开始查找 ③`size_t
find_last_of(const char* s,size_t pos,size_t n)const;`
找第1次出现C语言字符串s从pos开始,长度为n的子串的位置,
④
size_t find_last_of(char c,size_tpos=npos)const;
找第1次出现字符c的位置,默认从末尾开始查找
- substr
string& substr(size_t pos,size_t len = mpos)const
;
功能:截取子串,pos为截取的起始位置,len表示截取的长度
ok~以上就是string容器的基本接口介绍及其使用,当然,这些也不是全部的接口,只是一些比较常用的接口!更下详细的可以参考http://www.cplusplus.com/
各位看官要是觉得有所收获,留下你们的足迹!
以上是关于C++string使用的主要内容,如果未能解决你的问题,请参考以下文章