string类的基本使用及常用接口

本文详细介绍了C++标准库中的string类,包括基本使用(初始化、赋值、拷贝),迭代器的概念及其在正向、反向和常量迭代器上的应用,以及容器的容量管理、遍历、修改、查找和切割等关键操作。特别关注了操作符重载和非成员函数的使用,以及如何提高代码效率,如reserve和shrink_to_fit方法。
摘要由CSDN通过智能技术生成

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();
}
  1. n > size && n > capacity :增容(开新空间 + 拷贝 + 释放原有空间)+新的位置赋值(如果没有给默认字符,默认是 ‘\0’ )
  2. n < size:只修改size
  3. 当 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();
}
  1. reserve:调整容量大小:增加容量(原有基础上增加),不修改size,也可减少容量,按需减小,如果要减小的容量小于size,不做任何操作,如果要减小的容量大于size,则进行减小操作。
  2. PJ版string增容过程:如果为空字符串对象,初识容量大小为15,第一次增容为2倍,后续按照1.5倍增容。
  3. 可使用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常用接口

  1. 遍历:begin,end,operator[]

  2. 容量相关:size,resize,reserve

  3. 修改:+=,pop_back,swap

  4. 其他操作:c_str,find,rfind,substr

  5. 非成员函数:比较,>>,<<,getline

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值