string类基本使用
#include <string>
void test()
{
string str;//""
string str2("123");//"123"
string str3 = "abc";//"abc"
string str4("0123456789", 5);//"01234"
string cpy(str3);//"abc"
string str5(str4, 2, 2);//"23" 从str4的第2个位置拿两个字符创建一个字符串
string str6(10, a);//"aaaaaaaaaa"
str6 = str5;//操作符重载
str6 = "321";
str6 = "xyz";
}
迭代器
访问容器的一种通用方式, 所有支持迭代器的容器,其迭代器的使用方式完全相同。
迭代器的使用方式:类似于指针的使用方式,可以通过引用获取元素内容,可以通过++,–进行位置的移动。
- begin迭代器:第一个元素的位置
- end迭代器:最后一个元素的下一个位置
- 迭代器的范围,左闭右开[begin, end)
- 迭代器是一个可读可写的接口
正向迭代器
void test()
{
string str("0123456789");
//迭代器的遍历方式
string::iterator it = str.begin();
while(it != str.end())
{
//迭代器的解引用
cout << *it << " ";
//迭代器可读可写
*it = 'a';
//迭代器向后移动
++it;
}
cout << endl;
//#include<vector>
vector<int> vec = {1, 2, 3, 4, 5, 6, 7, 8, 9};
vector<int>::iterator vit = vec.begin();
while(vit != vec.end())
{
cout << *vit << " ";
++vit;
}
cout << endl;
}
反向迭代器
void test()
{
string str("123456789");
string::reverse_iterator rit = str.rbegin();
while(rit != str.rend())
{
cout << *rit << " ";
//反向迭代器向前移动
++rit;
}
cout << endl;
}
正向const迭代器
string::const_iterator cit = str.begin();
string::const_iterator cit2 = str.cbegin();
//const迭代器建议使用const接口获取:c...
while(cit != str.cend())
{//const迭代器不支持写操作,其为只读迭代器
cout << *cit << " ";
++cit;
}
const迭代器建议使用const接口
-
可读可写的迭代器iterator, reverse_iterator
-
只读迭代器const_iterator,const_reverse_iterator
-
begin();
iterator begin() —> 非const对象调用
const_iterator begin() const —> const对象调用 -
end();
iterator end() —> 非const对象调用
const_iterator end() const —> const对象调用 -
rbegin, rend 同上,也有两个接口
-
cbegin, cend, crbegin, crend —> 都返回const迭代器
size:返回有效字符的个数
length:返回有效字符的个数
capacity:可以存放的最大有效字符的个数
clear:只清空内容,不改变容量
capacity等接口
void test()
{
string str("0123456789");
//size:返回有效字符的个数(常用)
int ret = str.size();
//length:返回有效字符的个数
ret = str.length();
//capacity:可以存放的最大有效字符个数
ret = str.capacity();
size_t maxSize = str.max_size();
str.clear();
}
void test()
{
string str("0123456789");
int size = str.size();
int cap = str.capacity();
str.resize(20);//9之后用'\0'填充
size = str.size();
cap = str.capacity();
str.resize(10);
size = str.size();
cap = str.capacity();
str.resize(30, 'a');//9之后用'a'填充
size = str.size();
cap = str.capacity();
}
- n > size && n > capacity :增容(开新空间 + 拷贝 + 释放原有空间)+新的位置赋值(如果没有给默认字符,默认是 ‘\0’ )
- n < size:只修改size
- 当 n > size && n < capacity:新的位置赋值(如果没有给赋值字符,默认赋值 ‘\0’ + 修改size )
void test()
{
string str("0123456789");
int size = str.size();
int cap = str.capacity();
str.reserve(20);
size = str.size();
cap = str.capacity();
str.reserve(5);
size = str.size();
cap = str.capacity();
}
- reserve:调整容量大小:增加容量(原有基础上增加),不修改size,也可减少容量,按需减小,如果要减小的容量小于size,不做任何操作,如果要减小的容量大于size,则进行减小操作。
- PJ版string增容过程:如果为空字符串对象,初识容量大小为15,第一次增容为2倍,后续按照1.5倍增容。
- 可使用reserve提前开好空间,后续节省增容开销,提高代码效率
void test()
{
string s;
s.reserve(100);
int size = str.size();
int cap = str.capacity();
s.reserve(20);
size = str.size();
cap = str.capacity();
s.shrink_to_fit();
size = str.size();
cap = str.capacity();
}
shrink_to_fit()缩小容量到合适范围
遍历操作
operator[]可读可写接口,如str[i],如果越界,非法访问
at可读可写接口,如str.at(i),但是代码可读性不强,如果越界,抛异常
范围for也可读可写,如果需要修改,则接收类型为引用类型,底层通过迭代器实现
for(int i = 0; i < str.size(); i++)
{
cout << str[i] << " ";
}
for(int i = 0; i < str.size(); i++)
{
cout << str.at(i) << " ";
}
for(auto& ch : str)
{
cout << ch << " ";
}
back返回最后一个字符
front返回第一个字符
string类对象的修改操作
- push_back 尾插
- append 追加
string s;
s.push_back('a');// a
s.append(2, 'b');// abb 追加两个b
s.append("cde");// abbcde 追加cde
string s2;
s2.append(s);// abbcde 追加addcde
string s3;
s3.append(s, 3, 2);// cd 从s的第三个位置追加两个字符
char strArr[] = "1234";
s3.append(strArr, strArr + 2);// cd34 //从strArr第二个位置之后追加到s3
s3.append(s2.begin(), s2.end());// cd34abbcde 通过迭代器追加
- operator+= +=操作符重载(常用)
string s4;
s4 += '1'; //1
s4 += '234'; // 1234
s4 += s;// 1234abbcde
- inster 插入,除尾插之外插入效率较低O(n)
s4.inster(0, s3);//cd1234abbcde
s4.inster(0, s3, 7, 3);
s4.inster(s4.end(), 3, '1');
s4.inster(s4.end(), strArr + 1, strArr + 3);
- assign 赋值
s4.assign("11111");// 11111 效果和下面相同
s4 = "11111";
- erase 删除
s4.erase(0, 2);// 111
s4.erase(s4.begin());//11
s4.erase(s4.end());// 11 此时end迭代器位置非法,不做操作
s4.erase(s4.begin, s4.end());// "" 删完了
- replace 替换
string s = "0123456789";
s.replace = (3, 5, "aa");// 12aa89 从第三个元素开始替换五个字符
s.replace = (s.begin() + 1, s.end() - 1, "0");// 009 迭代器左闭右开,begin + 1第二个字符开始,end - 1指的是9
- swap 交换
string s2 = "abc";
s2.swap(s, s2);//s2: 009, s: abc
//调用string成员函数交换
swap(s, s2);//s2: abc, s: 009
//全局swap函数:内部调用string的成员函数swap完成交换
int a = 1;
int b = 2;
swap(a, b);
//全局任何类型的swap函数
- c_str、data,返回C风格的字符串,即字符串首元素地址,返回值类型是const char*
const char* ptr2 = s.c_str();
const char* ptr2 = s.data();
-
find正向查找,rfind反向查找,找到第一个匹配的位置 就结束,返回值类型为size_t
*找不到返回npos:static const size_t npos = -1, 可以通过与npos判断来确定是否找到*
string s = "aaaaaaaaaa";
size_t pos = str.find('a');
size_t pos2 = str.rfind('a');
- substr 截取字符串
- substr(pos, len) 如果len大于从pos到结束位置的字符串长度,则把剩余字符串全部截取出来
string str = "0123456789";
string str2 = str.substr(0, 5);//01234 从索引为0开始截取五个字符
-
operator+, 非成员函数,拼接字符串,返回一个string对象
-
operator>、operator=等关系运算符重载函数
按照ASCII码值比较大小,与长度无关
从第一个字符开始,逐字符比较,直到遇到不相等的字符出现,或者同时结束,按照不相等的码值确定大小
string s = "9";
string s2 = "123";
string s3 = "1234";
bool ret = s > s2; //true
ret = s2 > s3; //false
ret = s > s3; //true
- string支持>>和<<
cin:遇到空格,结束内容读取,如果读取的内容有空格,可以使用getline接口,getline(cin, s)遇到换行结束。还可以指定结束的标记字符,标记字符不会存放在string对象当中getline(cin, s, ‘。’)
string常用接口
string常用接口
-
遍历:begin,end,operator[]
-
容量相关:size,resize,reserve
-
修改:+=,pop_back,swap
-
其他操作:c_str,find,rfind,substr
-
非成员函数:比较,>>,<<,getline