首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【C++STL】一文掌握 String 核心接口:从基础到实用!

【C++STL】一文掌握 String 核心接口:从基础到实用!

作者头像
用户11960591
发布2025-12-23 15:47:13
发布2025-12-23 15:47:13
1230
举报

前言:结束了上一阶段的学习,在有了一定的语法基础以后下面我们就要进入C++的STL部分,STL在C++中占有极其重要的地位,下面我们就走进STL的世界,开始STL部分的学习。

一,STL简介

1.1 什么是STL?

STL的概念:STL(Standard Template Library)是C++标准库的核心组成部分,提供了一套通用的模板类和函数,用于实现常见的数据结构和算法。

1.2 STL的六大组件

STL的六大组件是它的核心我们在学习STL的时候也是围绕着这六大组件来进行学习,下面看看六大组件都有哪些:

在这里插入图片描述
在这里插入图片描述

1.3 如何学习STL

STL提供了一套通用的模板和函数,用于实现常见的数据结构,那么这些函数和数据结构我们首先要学会使用,其实就是了解一下这些数据结构的底层是如何实现的。 所以学习STL的步骤就是1.学会使用 2.了解底层 (后面的STL学习都会按照这两个步骤来学习)

声明:下面各种成员函数和非成员函数的参数返回值,可以去string文档中查询,链接:cpluspuls.com

二,第一个STL容器—string

2.1 string的4个默认构造的使用

函数名称

功能说明

string()

构造空的string类对象,即空字符串(重点)

string(const char* s)

用C风格字符串(C-string)构造string类对象(重点)

string(size_t n, char c)

构造包含n个字符c的string类对象

string(const string& s)

通过拷贝另一个string类对象构造新对象(重点)

我们先来看看库里面的一些函数重载:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
代码语言:javascript
复制
void TestString1()
{
	string s1;//创建一个空字符串对象
	string s2("hello world");//构造
	string s3(s2);//拷贝构造
	cout << s3 << endl;

	string s4(s2, 1, 8);//相当于memcopy
	//string s4(s1, 1, 60); 
	cout << s4 << endl;

	string s6(s2, 1);//不写长度那就从1开始拷贝 直到s2被拷贝完
	cout << s6 << endl;

	const char* str1 = "hello word"; 
	string s7(str1,5); //使用char* 的字符串构造
	cout << s7 << endl;

	string s8(100, '*');//将s8初始化成100个*
	cout << s8 << endl;
	
	//赋值运算符重载 s1.operator=()
	s1 = s2;
	s1 = "*******";
	cout << s1 << endl;
}

还有一个析构函数用于释放string内部的资源,在模拟实现部分会详细说明。

三,初识迭代器

3.1 使用迭代器遍历string

学习一个数据结构就要学会它的遍历,因为在使用数据结构的时候我们常常会修改数据结构内部的值,如果我们要一一进行修改那么就一定会用到遍历。在学习C语言的时候常见的遍历方式是使用for循环,while循环等,借助循环来遍历。而C++搞了一个新的遍历方式叫迭代器,它是所有容器的主流遍历方式,下面我们重点讲解它。

函数/语法

功能说明

begin + end

begin获取字符串第一个字符的迭代器,end获取最后一个字符下一个位置的迭代器

rbegin + rend

rbegin获取字符串最后一个字符的逆向迭代器,rend获取第一个字符前一个位置的逆向迭代器

范围for (C++11)

支持更简洁的范围遍历方式,无需显式使用迭代器或下标

1、传统遍历方式

代码语言:javascript
复制
void TestString2()
{
	string s1("hello word!");
	const string s2("hello bite");

	//s1[0]++ -> s1.operator[](0)++  使用重载的方括号
 
//第一种遍历方式 使用循环
//循环遍历字符串 并修改字符串  s1.size()是string类里的成员函数 返回的是字符串的大小
	for (size_t i = 0;i < s1.size();i++)
	{
		s1[i]++;
	}
	cout << s1 << endl;
}

2、使用迭代器

代码语言:javascript
复制
void TestString3()
{

string::iterator it1 = s1.begin();										
while (it1 != s1.end())
{
//it就是像指针一样的东西
	(*it1)++;//*it就可以拿到对应位置的数据 进行修改
	//(*it1)--;
}
cout << s1 << endl;

//将迭代器使用在顺序表(vector)
vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);

//这里的vector模板有显示限定 int
vector<int>::iterator it2 = v.begin();
while (it2 != v.end())
{
	cout << *it2 << " ";
	++it2;
}
cout << endl;
在这里插入图片描述
在这里插入图片描述

const迭代器与普通迭代器

在这里插入图片描述
在这里插入图片描述

正向迭代器和反向迭代器

在这里插入图片描述
在这里插入图片描述

3、auto关键字

还有另外一种遍历方式就是使用范围for。但在介绍范围for之前我们先来介绍一下auto关键字

代码语言:javascript
复制
void auto_test()
{
//auto是C++11支持的一种能够自动识别类型的关键字 
	auto x = 10;
	auto y = 10.1;
	cout << x << endl;//自动推出类型为int类型
	cout << y << endl;//自动推出类型为double类型

//auto声明引用类型时必须要使用&
	int& z = x;
	auto m = z;//这一步是赋值 如果想要m++ z和x也跟着++ 就要加上&即auto& m = z;
	m++;
	
	//用auto声明指针类型时,用auto和auto*没有任何区别
	auto p1 = &x;
	// 只能是指针
	auto* p2 = &x;
}
在这里插入图片描述
在这里插入图片描述

auto的注意事项:

  1. 当使用auto在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错。因为编译器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量。
  2. auto不能作为函数的参数,可以做返回值,但是建议谨慎使用
  3. auto不能直接用来声明数组

4、范围for

代码语言:javascript
复制
void TestString4()
{
	string s1("hello world");
	for(auto e:s1)
	{
		//范围for内部可以修改s1
		//e--;
		cout<<e<<endl;
	}
	//遍历vector
	vector<int> v;
	v.push_back(1);
	v.push_back(2);
	v.push_back(3);
	for (auto e : v)
	{
		cout << e << " ";
	}
	cout << endl;
}
在这里插入图片描述
在这里插入图片描述

范围for的注意事项:

  1. 范围for的三个自动:自动迭代、自动取数据、自动判断结束。这一点相比于上面的迭代器又更加的方便了,原因在于它是自动的。
  2. 范围for可以作用到数组和其他的容器对象上进行遍历。
  3. 范围for的底层其实就是替换为了迭代器,这也是它为什么能够支持遍历其他容器的原因。

总结—迭代器的意义: 1: 统一类似的方式遍历修改容器 2: 算法脱离具体底层结构,和底层结构解耦 3: 算法独立模板实现针对多个容器处理

四、string与容量有关的接口使用

4.1 string成员函数功能说明表

函数名称

功能说明

size(重点)

返回字符串有效字符长度

length

返回字符串有效字符长度

capacity

返回字符串分配的空间总大小

empty (重点)

检测字符串是否为空串,是则返回 true,否则返回 false

clear (重点)

清空字符串中的有效字符

reserve (重点)

为字符串预留空间

resize (重点)

将有效字符的个数调整为 n 个,多出的空间用字符 c 填充

代码语言:javascript
复制
void stringTest1()
{
	string s1("123456");

	//无论是s.size() 还是s.capacity()都是不包括\0的
	cout << s1.size() << endl;
	cout << s1.capacity() << endl; //capacity可能大于或等于字符串的长度 大于因为capacity底层会扩容
	cout << s1.length() << endl;
	
	//如果非空就打印
	if (!s1.empty())
	{
		cout << s1 << endl;
	}

	s1.clear();//清空字符串就是将size(有效数据个数)改成0
	cout << s1.size() << endl;

	string s2;
	size_t old = s2.capacity();
	cout << endl;
	cout << "s2.capacity:" << old << endl;
	//string的底层实际上就是一个顺序表,所以不断的往里面插入数据就会引发扩容逻辑
	for (size_t i = 0;i < 100;i++)
	{
		s2.push_back('x');
		if (s2.capacity() != old)
		{
			cout << "capacity:" << s2.capacity() << endl;
			old = s2.capacity();
		}
	}
//使用reserve 知道要开多少空间提前开好 避免多次扩容,提升效率
	s2.reserve(100);//扩容可以
	cout <<s2.capacity()<< endl;
	s2.reserve(5);//缩容不行
	cout <<s2.capacity()<< endl;

//resize 插入数据 让size达到我们定义的n 个
// n > capacity > size;
string s2("123456");
cout << endl;
s2.resize(20, '#');//这里n给20 那么size就从原来的6变成20,第二个参数不给默认用空格填充
cout << "size:" << s2.size() << endl;
cout << "capacity:" << s2.capacity() << endl;
}

上面的接口在使用中有几点需要注意:

  1. resize接口:是修改有效数据个数的接口,在改变元素个数时,如果是将元素个数增多,那么可能会影响capacity导致扩容,如果是将元素减少则底层总空间大小不变。
  2. reserve接口:是修改string总空间的接口,它不会影响有效数据个数。在改变空间大小时,如果比原来空间大那么久扩容到指定的这个空间,如果比原来的空间小并不会将空间缩小!!!
  3. clear接口:单纯修改有效数据个数,不改变底层的空间大小!

五、元素访问相关的接口

5.1 元素访问函数功能表格

函数名称

功能说明

区别

operator[] (重点)

返回 pos 位置的字符,const string 类对象可调用

若越界访问,行为未定义(可能崩溃或返回垃圾值)

at

返回 pos 位置的字符,提供边界检查

若越界访问,抛出 std::out_of_range 异常,安全性更高

:表格对比了两种访问字符串字符的方法,核心差异在于越界处理机制。

代码语言:javascript
复制
void stringTest3()
{
	//方括号操作符 本质是函数重载
	string s1("hello word!");
	s1[0]++;	
	cout << s1 << endl;
	//at用于返回该下标处的内容
	//cout << s1.at(2) << endl;
	s1.at(0)--;
	cout << s1 <<endl;
	//访问的下标越界 不属于当前空间 抛异常
	//s1.at(15);
}

六、修改相关的接口使用

6.1 修改相关的函数说明表格

函数名称

功能说明

push_back

在字符串末尾插入字符c

append

在字符串后追加一个字符串

operator+= (重点)

在字符串后追加字符串str

c_str (重点)

返回C格式的字符数组

find + npos(重点)

从字符串pos位置开始向后查找字符c,返回该字符在字符串中的位置

rfind

从字符串pos位置开始向前查找字符c,返回该字符在字符串中的位置

substr

在str中从pos位置开始,截取n个字符并返回

代码语言:javascript
复制
void test2()
{
	string s1("abcdefg");
	//string底层就是一个字符数组 对于string的操作就相当于对数组的操作
	s1.push_back('h');//push_back就是尾插往size位置处插入数据
	s1.push_back('i');

	s1.append("hello!JJJJ");//append就是往s1后面追加一个字符串
	cout << s1<< endl;

//c_str()用于当使用C语言想要打开C++的文件时,test.cpp就是一个string类型
//但是C语言又没有string这种东西 但是可以使用c_str返回C语言底层的那个字符数组这样就可以打开文件了
	string filename("test.cpp");
	FILE* fout = fopen(filename.c_str(), "r");
	if (fout == nullptr)
	{
		cout << "fopen error" << endl;
		return;
	}

	string s2("hello   world")
	size_t ret=s1.find(0," ");//find函数,从起始位置开始查找指定的字符,找到了返回该字符所在位置的下标
	//size_t ret2=s1.rfind(0," ")//refind接口就是从尾部开始倒着查找
	while (pos != string::npos)//npos 是string类里面定义的一个数据 它的类型是size_t 值为-1相当于是整型的最大值   所以npos就代表字符串能存储的最大长度pos!=npos就是说该位置如果不等于最大字符串长度 就说明找到了 否则就说明没找到 
	{
		s2[pos] = '#';
		//s2.replace(pos, 2,"##"); //replace接口 替换指定位置的字符
		pos = s2.find(' ',pos+2);
	}
	cout << s2 << endl;

	string s3=s2.substr(0, 5);//从s2中截取5个字符给s3
	cout << s3 << endl;
}

七,string类非成员函数(全局函数)

7.1 非成员函数功能表格

运算符/函数

功能说明

注意事项

operator+

字符串拼接,返回新字符串对象

传值返回导致深拷贝,频繁调用可能影响性能,建议少用

operator>> (重点)

输入运算符重载,从输入流提取内容到字符串,遇空格终止

需配合istream使用,注意处理缓冲区及错误状态

operator<< (重点)

输出运算符重载,将字符串内容插入到输出流

常用于日志打印或控制台输出,无格式限制

getline (重点)

从输入流读取一行字符串(包括空格),可指定分隔符

需清除换行符残留,避免与operator>>混用时出错

relational operators (重点)

比较字符串大小(如==, !=, <, >等),按字典序逐字符对比

区分大小写,比较前需确保字符串非空或已初始化

代码语言:javascript
复制
void stringTest8()
{
string s1("hello"), s2("hello");
cout << s1 << " " << s2 << endl;
string s3 = s1 + s2;//operator+用于字符串拼接
cout << s3 << endl;//流插入重载

bool a = s1 == s2;//判断大小关系 有== >= <= < > !=
cout << a << endl;
//cin >> s1 >> s2;//流提取重载
//cout << s1 <<" "<< s2 << endl;

string line;
//cin >> line;//流插入重载

getline(cin, line);//获取一行字符串 区别与scanf scanf识别到空格就结束 
//而getline不同 getline是识别到换行才结束
cout << line << endl;
}

注意:这里的函数之所以搞成全局函数而不搞成string内部的函数是因为,如果搞成string内部函数那么第一个参数就定死了是string类型。因为成员函数中第一个参数要传给this指针,this指针的类型就是该类的类型。这些函数如果重载成成员函数就无法实现const char* 的类型作为参数了!

以上就是本篇文章的所有内容了,感谢各位大佬观看,制作不易还望各位大佬点赞支持一下!有什么问题可以加我私信交流!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-12-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一,STL简介
    • 1.1 什么是STL?
    • 1.2 STL的六大组件
    • 1.3 如何学习STL
  • 二,第一个STL容器—string
    • 2.1 string的4个默认构造的使用
  • 三,初识迭代器
    • 3.1 使用迭代器遍历string
  • 四、string与容量有关的接口使用
    • 4.1 string成员函数功能说明表
  • 五、元素访问相关的接口
    • 5.1 元素访问函数功能表格
  • 六、修改相关的接口使用
    • 6.1 修改相关的函数说明表格
  • 七,string类非成员函数(全局函数)
    • 7.1 非成员函数功能表格
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档