当前位置: 首页 > news >正文

C++—string类接口与用法大总结(其中涉及STL基础)

目录

1.string类的本质

2.string类的构造

1.普通构造

2.功能型构造

1.拷贝构造功能型

2.带参构造功能型

3.其余构造

3.operator[]

4.迭代器(iterator)

1.概念

2.改变string对象本身

3.正向迭代器(iterator)

4.反向迭代器(reverse_iterator)

5.const迭代器

1.const正向迭代器(const_iterator)

2.const反向迭代器(const_reverse_iterator)

5.范围for(遍历与修改)

0.auto

1.概念

2.不改变string对象本身

3.改变string对象本身

6.容量系列

1.size:求有效数据个数(不算'\0')

2.capacity:求顺序表容量

3.reserve:用于扩容和缩容

1.扩容:

2.缩容:

7.增删系列

1.push_back:尾插一个字符

2.append:尾插一个字符串

3.operator+=:拼接字符或字符串

4.insert:在指定下标插入字符串或字符

1.插入字符串:

2.插入字符:

5.erase:从指定下标开始删除k个字符

8.replace:替换

9.find:查找(找到指定内容并返回其第一次出现的下标)

10.swap:交换函数

11.c_str:返回string类的指针成员变量(本质是为了兼容C语言)

12.substr:从某个下标开始的k个字符构造成一个新的string对象并返回

13.find_first_of:从s1中找是否存在我传过去的字符串中的任意一个字符,如果比对成功则返回下标

14.operator+

15.getline:默认遇到\n才会停止在缓冲区中取数据(cin默认遇到空格和\n就会停止在缓冲区中取数据)


1.string类的本质

string类是由字符组成的顺序表。

2.string类的构造

1.普通构造

#include <iostream>
#include <string>
using namespace std;
int main()
{//默认构造string s1;//带参构造string s2("111111");//拷贝构造string s3(s2);cout << s1 << endl;cout << s2 << endl;cout << s3 << endl;
}

结果:

2.功能型构造

1.拷贝构造功能型

string s1("hello world");//拷贝构造功能型//从下标为6的字符开始拷贝5个字符
string s2(s1, 6, 5);
//如果第三个参数超出了字符串的范围,就是从下标为6开始、打印完就结束
string s3(s1, 6, 50);
//省略第三个参数的话,就是从下标为6开始、打印完就结束
string s4(s1, 6);cout << s1 << endl;
cout << s2 << endl;
cout << s3 << endl;
cout << s4 << endl;

结果:

2.带参构造功能型

//拿字符串前5个字符构造
string s1("hello world",5);
cout << s1 << endl;

结果:

3.其余构造

//拿10个X组成字符串构造
string s1(10, 'X');
cout << s1 << endl;

结果:

3.operator[]

string类中重载了[]运算符,使其能够像数组一样使用。

class string
{
public:char& operator[](int x){return arr[x];}private:char* arr;int size;int capacity;
};

用引用返回是为了能够改变指定下标的值。

string s1("hello world");
s1[0] = 'X';
cout << s1 << endl;

结果:

4.迭代器(iterator)

1.概念

s1.begin()指向第一个元素,s1.end()指向最后一个元素的下一个元素。(最后一个元素指的是最后一个有效元素)

string s1("hello");
string::iterator it = s1.begin();
while (it != s1.end())
{cout << (*it)<<"  ";it++;
}
cout << endl;

注意:这里的it可以当指针理解,但本质不一定是指针。

结果:

2.改变string对象本身

string s1("hello");
string::iterator it = s1.begin();
while (it != s1.end())
{//这里会改变s1的每个变量*it += 2;it++;
}
cout << s1 << endl;

结果:

3.正向迭代器(iterator)

s1.begin()指向第一个元素,s1.end()指向最后一个元素的下一个元素。(最后一个元素指的是最后一个有效元素)

string s1("hello");
string::iterator it = s1.begin();
while (it != s1.end())
{cout << (*it)<<"  ";it++;
}
cout << endl;

结果:

4.反向迭代器(reverse_iterator)

rbegin指向最后一个元素,rend指向第一个元素的前一个元素。

string s1("hello");
string::reverse_iterator rit = s1.rbegin();
while (rit != s1.rend())
{cout << *rit << "  ";rit++;
}

结果:

5.const迭代器

1.const正向迭代器(const_iterator)

const string s3("hello world");
string::const_iterator cit = s3.begin();
while (cit != s3.end())
{//不能*cit += 2;cout << *cit << " ";++cit;
}
cout << endl;

2.const反向迭代器(const_reverse_iterator)

const string s3("hello world");
string::const_reverse_iterator rcit = s3.rbegin();
while (rcit != s3.rend())
{// 不能*rcit += 2;cout << *rcit << " ";++rcit;
}
cout << endl;

5.范围for(遍历与修改)

范围for适用于容器和数组

0.auto

auto是用来自动推导类型的。

string s1("hello");
//string::iterator it = s1.begin();//这里的迭代器也可以这么写:
auto it = s1.begin();
//这样写编译器会自动推导出auto此时的位置应该是一个迭代器类型

auto存在的目的是为了简化代码,但弊端就是降低了代码的可读性。

1.概念

string s2("hello");
//范围for底层是一个迭代器
//这里的x相当于拷贝的*it
for (auto x : s2)
{cout << x << "  ";
}

结果:

2.不改变string对象本身

string s2("hello");
//范围for底层是一个迭代器
//这里的x相当于拷贝的*it
for (auto x : s2)
{//这里不会改变s2字符串本身,因为x变量只是拷贝x += 2;cout << x << "  ";
}cout << endl << s2 << endl;

结果:

3.改变string对象本身

string s2("hello");
//范围for底层是一个迭代器
//这里的x相当于*it的别名
for (auto& x : s2)
{//这里会改变s2字符串本身,因为x变量是引用的s2中的每一个变量x += 2;cout << x << "  ";
}cout << endl << s2 << endl;

结果:

6.容量系列

1.size:求有效数据个数(不算'\0')

string s1("hello");
cout << s1.size() << endl;

结果:

2.capacity:求顺序表容量

string s1("hello");
cout << s1.capacity() << endl;

结果:

3.reserve:用于扩容和缩容

1.扩容:

s1.reserve(100);

假如上述语句是在扩容,那么容量会变成比100要大或者等于100的数。

2.缩容:

s1.reserve(2);

假如上述语句是在缩容,那么容量会不会变小不好说,取决于编译器,但是最起码能够保证的是,它绝对不会因为缩容而影响你原来的数据。

7.增删系列

1.push_back:尾插一个字符

string s1("hello");
s1.push_back('o');
cout << s1 << endl;

结果:

2.append:尾插一个字符串

这里的众多接口与前面讲到的构造类似,所以不再过多赘述。

string s1("hello");
s1.append("xxx");
cout << s1 << endl;

结果:

3.operator+=:拼接字符或字符串

string s1("hello");
s1 += ' ';
s1 += "world";
cout << s1 << endl;

结果:

4.insert:在指定下标插入字符串或字符

1.插入字符串:

string s1("hello");
//在下标为1的位置插入xxx
s1.insert(1, "xxx");
cout << s1 << endl;

结果:

2.插入字符:

string s1("hello");
char ch = 'x';
//在下标为0的位置插入2个ch字符
s1.insert(0, 2, ch);
cout << s1 << endl;

结果:

这里的第二个参数不能省略从而变成插入1个字符,可见C++中的string类的设计是有一些冗余的。

5.erase:从指定下标开始删除k个字符

string s1("hello world");
//从指定下标0开始删除1个数据
s1.erase(0, 1);
cout << s1 << endl;

结果:

string s1("hello world");
//若省略第二个参数,则从指定下标6开始删除直到结束
s1.erase(6);
cout << s1 << endl;

结果:

8.replace:替换

string s1("hello world");
//将下标为5起始的4个元素替换
s1.replace(5, 4, "xxx");
cout << s1 << endl;

结果:

9.find:查找(找到指定内容并返回其第一次出现的下标)

string s1("hello world");//返回找到的下标,如果没找到,则返回npos
int pos = s1.find("hello");
cout << pos << endl;

结果:

string s1("hello world  hello  hello ");//返回找到的下标(从3下标开始找),如果没找到,则返回npos
int pos = s1.find("hello",3);
cout << pos << endl;

结果:

10.swap:交换函数

swap函数用来交换两个对象的所有成员变量。

string s1("hello xxx");
string s2("hello yyy");
s1.swap(s2);
cout << s1 << endl;
cout << s2 << endl;

结果:

11.c_str:返回string类的指针成员变量(本质是为了兼容C语言)

class string
{
public:private:char* arr;int size;int capacity;
};
string s1("hello xxx");
string s2("hello yyy");
const char* str1 = s1.c_str();

这里的s1.c_str()返回的就是s1.arr

12.substr:从某个下标开始的k个字符构造成一个新的string对象并返回

//例如我想找到一个文件后缀名
string s1("test.cpp");
int pos = s1.rfind('.');
string s2 = s1.substr(pos);
cout << s2 << endl;

结果:

13.find_first_of:从s1中找是否存在我传过去的字符串中的任意一个字符,如果比对成功则返回下标

这个接口作者本人觉得命名不太好,应该改成find_any_of会更容易理解一些

string s1("hello world");
cout<<s1.find_first_of("abcde")<<endl;

结果:

string s1("hello world");
//从下标为3的位置开始找
cout<<s1.find_first_of("abcde",3)<<endl;

结果:

还有一个接口是find_last_of,而这个接口就是将find_first_of换成倒着找而已。说实话这个名字取得也有点矬,应该取名为rfind_any_of会更好一些(作者吐槽)。

14.operator+

string s1("abc");
string s2 = "de" + s1;
cout << s2 << endl;

结果:

15.getline:默认遇到\n才会停止在缓冲区中取数据(cin默认遇到空格和\n就会停止在缓冲区中取数据)

string s1;
//默认遇到\n才会停止取数据
getline(cin, s1);
cout << s1 << endl;

结果:

string s1;
//默认遇到*才会停止取数据
getline(cin, s1,'*');
cout << "——————————————"<<endl;
cout << s1 << endl;

结果:


http://www.mrgr.cn/news/30584.html

相关文章:

  • 【Vmware16安装教程】
  • 登录后继续执行方法
  • pg入门3—详解tablespaces2
  • RK3568平台(网络篇)MAC地址烧录
  • 【LabVIEW】事件结构的用法
  • 消息队列-Kafka(概念篇)
  • 小琳AI课堂:强化学习初阶
  • OJ在线评测系统 前端开发设计优化通用菜单组件二 调试用户自动登录
  • JavaFX实现视频播放功能
  • SPI接口通信协议浅谈成都自动化开发
  • yolov5/8/9/10模型在VOC数据集上的应用【代码+数据集+python环境+GUI系统】
  • Linux 后台运行服务的全攻略:nohup、screen、tmux 和 systemd 的实战指南
  • (笔记)mac笔记本调节键盘速率
  • 【大模型开发】 迎接AI新时代:Qwen2.5发布,超越LLaMA3!本地私有化部署:如何通过一键API调用不同模型?(附源码地址)
  • C++——求3个数中最大的数(分别考虑整数、双精度数、长整数的情况),用函数模板来实现。
  • 前端框架对比和选择
  • 6. 什么是MySQL的事务?如何在Java中使用Connection接口管理事务?
  • chapter16-坦克大战【1】——(自定义泛型)——day21
  • JZ2440开发板——S3C2440的存储控制器
  • C++ prime plus-3-编程练习