C++第五讲(1):STL--string--各个函数的使用方法

news2024/11/17 13:28:17

C++第五讲:STL--string

  • 1.STL简介
  • 2.string类
    • 2.1string类的常见构造
      • 2.1.1重点1: string()
      • 2.1.2重点2:string(const string& str)
      • 2.1.3使用3:string(const string& str, size_t pos, size_t len = npos)
      • 2.1.4重点3:string(const char* s)
      • 2.1.5使用5:string(const char* s, size_t n)
      • 2.1.6使用6:string(size_t n, char c)
    • 2.2迭代器
    • 2.3auto关键字
    • 2.4范围for
  • 3.string类常用功能详细介绍
    • 3.1Member functions(成员函数)
      • 3.1.1constructor -- 构造函数 -- 重点
      • 3.1.2destructor -- 析构函数
      • 3.1.3operator= -- =运算符重载
    • 3.2Iterators -- 迭代器
      • 3.2.1begin -- 重点
      • 3.2.2end -- 重点
      • 3.2.3rbeign -- 重点
      • 3.2.4rend -- 重点
      • 3.2.5cbegin
      • 3.2.6cend
      • 3.2.7crbegin
      • 3.2.8crend
    • 3.3Capacity -- 容量
      • 3.3.1size -- 重点
      • 3.3.2length
      • 3.3.3max_size
      • 3.3.4resize -- 重点
      • 3.3.5capacity -- 重点
      • 3.3.6reserve -- 重点
      • 3.3.7clear -- 重点
      • 3.3.8empty
      • 3.3.9shrink_to_fit
    • 3.4Element access -- 元素访问
      • 3.4.1operator[] -- 重点
      • 3.4.2at
      • 3.4.3back
      • 3.4.4front
    • 3.5Modifiers -- 修改器
      • 3.5.1operator+= -- 重点
      • 3.5.2append
      • 3.5.3push_back
      • 3.5.4assign
      • 3.5.5insert -- 重点
      • 3.5.6erase -- 重点
      • 3.5.7replace
      • 3.5.8swap
      • 3.5.9pop_back
    • 3.6String operations -- 字符串操作
      • 3.6.1c_str -- 重点
      • 3.6.2data
      • 3.6.3copy
      • 3.6.4find -- 重点
      • 3.6.5rfind -- 重点
      • 3.6.6find_first_of
      • 3.6.7find_last_of
      • 3.6.8find_first_not_of
      • 3.6.9find_last_not_of
      • 3.6.10substr -- 重点
      • 3.6.11compare
    • 3.7getline

1.STL简介

STL(standard template library - 标准模板库),是C++标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架,但是不能说标准库就是STL,因为标准库中包含STL,其中还有着其它很多东西

STL有6大组件,其中一大组件叫做容器,我们今天要介绍的就是容器之一:string

2.string类

说string是容器,其实string就是一个类,底层是基于动态数组实现的,所以string创建出的对象,都存储在堆上,而实际上string类是basic_string的一个特化版本,basic_string是一个模板类,有着更强的通用性,通过改变模板类的模板参数,能够处理不同字符类型的数据,如宽字符、Unicode字符等,而string的定义为:
typedef basic_string<char> string;
所以string是专门为char类型字符设计的,下面我们要学习关于string类的相关知识

2.1string类的常见构造

//对于string的常见类函数,如果是经常要用的就使用重点说明,不是重要的就没有重点说明
       default (1)   string();
       //重点1:该函数可以构造一个空的string类对象,即一个空的字符串
           copy(2)   string(const string& str);
           //重点2:拷贝构造函数
      substring(3)   string(const string& str, size_t pos, size_t len = npos);
      //从pos位置开始拷贝,拷贝到字符串结束(当str的长度太短,小于npos 或者 拷贝到npos位置)
from c - string(4)   string(const char* s);
//重点3:用C-string来构造string类对象
  from sequence(5)   string(const char* s, size_t n);
  //拷贝S指向字符的前n个字符
           fill(6)   string(size_t n, char c);
           //使用n个字符c填充字符串
          range(7)   template <class InputIterator>
                     string(InputIterator first, InputIterator last);
          //从[first, last)按照顺序拷贝
          //Copies the sequence of characters in the range [first,last), in the same order.

上面是通过cplusplus网站看的string类函数,下面我们详细使用一下这些构造:

2.1.1重点1: string()

default (1)	   string();
//重点1:该函数可以构造一个空的string类对象,即一个空的字符串

函数使用:

int main()
{
	//string类本来是存在于std中的,因为我们对std全部展开了,所以我们可以直接使用string函数
	//std::string s1;
	string s1;

	return 0;
}

2.1.2重点2:string(const string& str)

copy(2)   string(const string& str);
//拷贝构造函数

函数使用:

int main()
{
	//重点1:
	string s1;

	//重点2:
	string s2("hello world!");
	cout << s2 << endl;
	string s3(s2);
	cout << s3 << endl;
	return 0;
}

2.1.3使用3:string(const string& str, size_t pos, size_t len = npos)

substring(3)   string(const string& str, size_t pos, size_t len = npos);
//从pos位置开始拷贝,拷贝到字符串结束(当str的长度太短,小于npos 或者 拷贝到npos位置)
int main()
{
	//重点1:
	string s1;

	//重点2:
	string s2("hello world!");
	cout << s2 << endl;
	string s3(s2);
	cout << s3 << endl;

	//使用3:
	string s4(s2, 0, 5);//【0, 5)
	cout << s4 << endl;
	//如果npos大于string的长度或者npos未赋值,就将所有字符进行拷贝
	//npos为赋值
	string s5(s2, 0);
	cout << s5 << endl;
	//npos的长度大于string的长度
	string s6(s2, 0, 20);
	cout << s6 << endl;

	return 0;
}

2.1.4重点3:string(const char* s)

from c - string(4)   string(const char* s);
//重点3:用C-string来构造string类对象
int main()
{
	//重点1:
	string s1;

	//重点2:
	string s2("hello world!");
	cout << s2 << endl;
	string s3(s2);
	cout << s3 << endl;

	//使用3:
	string s4(s2, 0, 5);//【0, 5)
	cout << s4 << endl;
	//如果npos大于string的长度或者npos未赋值,就将所有字符进行拷贝
	//npos为赋值
	string s5(s2, 0);
	cout << s5 << endl;
	//npos的长度大于string的长度
	string s6(s2, 0, 20);
	cout << s6 << endl;

	//重点3:
	string s7("hello ABCD!");
	cout << s7 << endl;

	return 0;
}

2.1.5使用5:string(const char* s, size_t n)

from sequence(5)   string(const char* s, size_t n);
//拷贝S指向字符的前n个字符
int main()
{
	//重点1:
	string s1;

	//重点2:
	string s2("hello world!");
	cout << s2 << endl;
	string s3(s2);
	cout << s3 << endl;

	//使用3:
	string s4(s2, 0, 5);//【0, 5)
	cout << s4 << endl;
	//如果npos大于string的长度或者npos未赋值,就将所有字符进行拷贝
	//npos为赋值
	string s5(s2, 0);
	cout << s5 << endl;
	//npos的长度大于string的长度
	string s6(s2, 0, 20);
	cout << s6 << endl;

	//重点3:
	string s7("hello ABCD!");
	cout << s7 << endl;

	//使用5:
	string s8("hello abcd!", 4);
	cout << s8 << endl;

	return 0;
}

2.1.6使用6:string(size_t n, char c)

fill(6)   string(size_t n, char c);
//使用n个字符c填充字符串
int main()
{
	//重点1:
	string s1;

	//重点2:
	string s2("hello world!");
	cout << s2 << endl;
	string s3(s2);
	cout << s3 << endl;

	//使用3:
	string s4(s2, 0, 5);//【0, 5)
	cout << s4 << endl;
	//如果npos大于string的长度或者npos未赋值,就将所有字符进行拷贝
	//npos为赋值
	string s5(s2, 0);
	cout << s5 << endl;
	//npos的长度大于string的长度
	string s6(s2, 0, 20);
	cout << s6 << endl;

	//重点3:
	string s7("hello ABCD!");
	cout << s7 << endl;

	//使用5:
	string s8("hello abcd!", 4);
	cout << s8 << endl;

	//使用6:
	string s9(10, 'x');
	cout << s9 << endl;

	return 0;
}

使用7:因为使用7涉及到了后续的内容,所以使用7之后会使用到

2.2迭代器

C语言中,数组的访问使用的是【】,而string是一个类,访问起来比较困难,所以C++就重载了【】运算符,使得string创建的对象也可以使用【】来访问了,所以我们遍历string的对象,可以这样:

int main()
{
	string s1("hello world!");

	for (int i = 0; i < s1.size(); i++)
	{
		cout << s1[i] << " ";
	}
	cout << endl;

	return 0;
}

这样访问起来就方便多了,但是还有更加方便的,称为算法糖,因为这个算法使我们用起来十分的方便:

//迭代器的使用
//迭代器提供了一种遍历 容器(注意是容器才有迭代器的概念) 中元素的方法,这样我们就无需关心容器内部的实现细节 
int main()
{
	string s1("hello world!");
	//iterator本身就有迭代器的意思,它被封装到string类里边
	string::iterator it = s1.begin();//s1.begin()是返回字符串起始位置的地址
	//这里使用起来就不需要关注字符串长度什么了
	while (it != s1.end())
	{
		//使用起来类似于指针
		cout << *it << " ";
		it++;
	}
	cout << endl;

	return 0;
}

begin和end指向的位置为:
在这里插入图片描述

上面展示的是正向迭代器,还有反向迭代器,反向迭代器支持逆序遍历:

//反向迭代器的使用
int main()
{
	string s1("hello world!");
	string::reverse_iterator rit = s1.rbegin();//既然是反向迭代器,就是rbegin
	while (rit != s1.rend())
	{
		cout << *rit << " ";
		rit++;//这里也是++,不是--
	}
	cout << endl;

	return 0;
}

rbegin和rend指向的位置为:
在这里插入图片描述

我们现在需要了解的迭代器可以说有四种:正向迭代器,反向迭代器,const 正向迭代器, const 反向迭代器,下面我们将const的两个迭代器的使用展示展示:

这里需要注意的是:权限的问题:

//const迭代器的使用
int main()
{
	const string s1("hello world!");

	string::iterator it = s1.begin();//err:无法从String_const_iterator转换为String_iterator
	//所以这里和权限的扩大还挺相似的
	while(it != s1.end())
	{
		cout << *it << " ";
		it++;
	}
	cout << endl;

	return 0;
}
//const迭代器的使用
int main()
{
	const string s1("hello world!");

	//const正向迭代器的使用
	string::const_iterator it = s1.begin();
	while (it != s1.end())
	{
		//(*it)++;  //这里的it指向的数据就不能修改了!!!
		cout << *it << " ";
		it++;
	}
	cout << endl;

	//const反向迭代器的使用
	string::const_reverse_iterator rit = s1.rbegin();
	while (rit != s1.rend())
	{
		cout << *rit << " ";
		rit++;
	}
	cout << endl;

	return 0;
}

2.3auto关键字

之前我们定义整形数据时,我们会使用:int a = 10;,但是有了auto,我们就不需要判断返回值了:

//auto关键字使用:
int func()
{
	return 1;
}

int main()
{
	auto a = 10;  //int a
	auto b = 'c'; //char b
	auto pa = &a; //int* pa
	auto c = func();//int c
	//auto d;//err:类型包含auto的符号必须具有初始值设定项

	return 0;
}

我们看到这还不能完全理解auto的好用之处,比我我们刚看的迭代器的使用,也可以用auto:

int main()
{
	string s1("hello world!");
	auto it = s1.begin();//这里使用auto就非常方便了
	while (it != s1.end())
	{
		cout << *it << " ";
		it++;
	}
	cout << endl;

	return 0;
}

需要注意的是:auto可以声明指针类型,但是auto声明引用类型时,必须加上&:

int main()
{
	int a = 10;
	int& b = a;
	auto c = b;//这里的c还是int类型,不是int&类型,如果想要int&类型的话,需要这样使用:
	auto& d = a;//int& d = a

	return 0;
}

auto不能作为函数参数,但是能作为函数返回值,但是这个需要谨慎使用,因为在大型项目中,如果函数体很大的话,推出auto返回值类型还是有难度的

//auto可以做函数返回值
auto func1()
{
	return 1;
}
//不能做函数参数
auto func2(auto x)//err:参数不能包含auto的类型
{}

int main()
{

	return 0;
}

auto不能直接来声明数组

int main()
{
	auto arr[] = { 1, 2, 3, 4 };//err:auto不能出现在顶级数组类型中

	return 0;
}

2.4范围for

范围for的底层其实就是使用迭代器实现的,这个可以看一看汇编层就可以看出来,C语言中的for循环,使用时需要判断结束条件,需要自己++,有了范围for,就不需要这些了,范围for可以自己++,自己判断结束条件,使用方法如下:

int main()
{
	string s1("hello world!");
	//自己判断结束条件,自己++
	for (auto ch : s1)
	{
		cout << ch << " ";
	}
	cout << endl;

	return 0;
}

但是,我们看下面的代码:

int main()
{
	int array[] = { 1, 2, 3, 4, 5 };
	for (auto e : array)
	{
		e *= 2;//这里我们想要改变数组中的值
	}
	for (auto e : array)
	{
		cout << e << " ";//输出:1, 2, 3, 4, 5,发现数组中的数据没变!
	}
	cout << endl;

	return 0;
}

数组中的数据没变!这是因为这个冒号(:)的作用为:自动取数据赋值给左边,因为是赋值,所以是浅拷贝,如果想要改变元素据的话,需要使用引用,而auto不会自己识别引用,所以需要自己手动加上&运算符:

int main()
{
	int array[] = { 1, 2, 3, 4, 5 };
	//别名:
	for (auto& e : array)
	{
		e *= 2;
	}
	for (auto e : array)
	{
		cout << e << " ";//输出:2,4,6,8,10,这时就发生改变了!
	}
	cout << endl;

	return 0;
}

有了上面的基础知识了之后,我们继续看string这个容器内的内容:

3.string类常用功能详细介绍

3.1Member functions(成员函数)

3.1.1constructor – 构造函数 – 重点

这个在刚开始就已经讲过了,所以这里就不再讲

在这里插入图片描述

3.1.2destructor – 析构函数

这个就是string类的析构函数,不用过多关注

3.1.3operator= – =运算符重载

该运算符重载的使用有三个接口:
在这里插入图片描述
该运算符的功能为:为string赋一个新值,覆盖掉它原来的组成

int main()
{
	string s1("hello world!");//原来的值
	s1 = "hello";//字符串进行赋值
	s1 = 'x';//字符进行赋值
	string s2 = s1;//类与类之间的赋值

	cout << s1 << endl;
	cout << s1 << endl;

	return 0;
}

3.2Iterators – 迭代器

这里面都是针对迭代器产生的一系列接口

3.2.1begin – 重点

在这里插入图片描述
该接口的作用为:返回指向string第一个字符的迭代器:
在这里插入图片描述

3.2.2end – 重点

在这里插入图片描述
该接口的作用为:返回指向string类最后一个字符的下一个字符的迭代器:
在这里插入图片描述

begin和end可以同时使用:

int main()
{
	string s1("hello world!");

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

	return 0;
}

3.2.3rbeign – 重点

在这里插入图片描述
该接口的作用为:返回指向string最后一个字符的反向迭代器:
在这里插入图片描述

3.2.4rend – 重点

在这里插入图片描述
该接口的作用为:返回string第一个字符的前一个位置的反向迭代器:
在这里插入图片描述

rbegin也会和rend配套使用:

int main()
{
	string s1("hello world!");

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

	return 0;
}

3.2.5cbegin

在这里插入图片描述
该函数的作用为:返回指向string第一个字符的const迭代器:
在这里插入图片描述
所以使用的时候就不能够修改迭代器指向的字符串了:

int main()
{
	const string s1("hello world!");

	string::const_iterator rit = s1.cbegin();
	while (rit != s1.cend())
	{
		//(*rit)++;//err:表达式必须是可以修改的左值
		cout << *rit << " ";
		rit++;
	}
	cout << endl;

	return 0;
}

3.2.6cend

因为这几个接口和之前的接口相似,所以这里就不过多展示了:

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

3.2.7crbegin

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

3.2.8crend

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

3.3Capacity – 容量

3.3.1size – 重点

在这里插入图片描述
该接口的作用为:返回string这个类中存储数据的长度,就字节方面而言
在这里插入图片描述

int main()
{
	string s1("hello world!");

	cout << s1.size() << endl; //12

	return 0;
}

3.3.2length

这个和size的功能的完全相同的,但是不建议用这个,因为这个是在早期实现的,后期因为length并不能够完全适配STL库中的其它类,所以就令实现了一个size,所以用size即可

在这里插入图片描述

3.3.3max_size

在这里插入图片描述
该接口的功能为:返回string能够开辟的最大空间:
在这里插入图片描述
但是这个空间往往是不准确的,只是理论上能够达到的最大空间,所以我们往往不会使用这个接口:

int main()
{
	string s1("hello world!");

	cout << s1.max_size() << endl; //9223372036854775807

	return 0;
}

3.3.4resize – 重点

在这里插入图片描述

//该函数的功能为:重新调整string的大小,使它的大小变为n个字符
//1.如果n小于原来的string长度时:空间缩小到n ,但是它的capacity不变
//2.如果n大于原来的字符长度时:
//  2.1当char c为传值时,将多开辟的空间赋值为0,即\9
//  2.2当char c传值时,将多开辟的空间赋值为c,并不会影响到原来string里的数据
int main()
{
	string s1("hello world!");

	s1.resize(19);
	s1.resize(29, 'x');

	return 0;
}

在这里插入图片描述

3.3.5capacity – 重点

在这里插入图片描述
该函数的作用为:返回已经开辟好的空间大小,单位为字节

//string的底层中,其实有一个Buf数组,该数组的初始空间为15
//如果string需要存储的数据少于15时,就会直接使用该数组进行存储,因为开辟空间需要消耗效率
//而且第一次扩容,是2倍扩容,后续都是1.5倍扩容的
int main()
{
	string s1("x");
	cout << s1.capacity() << endl;//15 //其实是16个字节大小,因为\0不计入空间大小计算

	string s2("hello world");
	cout << s2.capacity() << endl;//15

	string s3("xxxxxxxxxxxxxxxxxx");
	cout << s3.capacity() << endl;//31

	string s4("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
	cout << s4.capacity() << endl;//47

	return 0;
}

3.3.6reserve – 重点

在这里插入图片描述
该函数的作用为:为string预开辟一块空间,具体内容看下面的代码注释:

int main()
{
	string s1;
	s1.reserve(20);//capacity = 31 //因为VS中开辟空间时可能会考虑对齐的问题,所以开辟的空间和预开辟空间可能会不一样,但是肯定够用
	cout << s1.capacity() << endl;//31

	string s2("hello world!");
	s2.reserve(30);

	string s3("hello world!");
	s3.reserve(5);
	cout << s3.capacity() << endl;//15,当预开辟的空间小于原来字符串的空间时,将会提供一个没有约束力的要求去缩小字符串
	//反而这个函数恰恰没有条件改变字符串的长度和内容

	return 0;
}

3.3.7clear – 重点

在这里插入图片描述
该函数的作用为:删除string的中的内容,并且使string中的size变为0:

int main()
{
	string s1("hello world!");
	cout << s1 << endl;//hello world
	cout << s1.capacity() << endl;//15

	s1.clear();
	cout << s1 << endl;//什么也没有打印
	cout << s1.capacity() << endl;//15

	return 0;
}

3.3.8empty

在这里插入图片描述
该函数的作用为:检查string是否为空,也就是检查string的size是否为0:

int main()
{
	string s1("hello world!");
	cout << s1.empty() << endl;//0,非空

	s1.clear();
	cout << s1.empty() << endl;//1,为空

	return 0;
}

3.3.9shrink_to_fit

在这里插入图片描述
该函数的作用为:因为resize和clear都无法改变string的capacity,所以提供了一个改变string capacity的函数,该函数可以要求string改变它的capacity去适应它的size:

int main()
{
	std::string str(100, 'x');
	std::cout << "1. capacity of str: " << str.capacity() << '\n';//111

	str.resize(10);
	std::cout << "2. capacity of str: " << str.capacity() << '\n';//111:resize没有改变str的capacity

	str.shrink_to_fit();
	std::cout << "3. capacity of str: " << str.capacity() << '\n';//15:这时capacity就发生了改变

	return 0;
}

3.4Element access – 元素访问

3.4.1operator[] – 重点

在这里插入图片描述
该函数的作用为:返回一个指向string pos位置字符的引用:

这个就不用再进行演示了,因为前面已经用过多次了

3.4.2at

在这里插入图片描述
该函数的作用为:返回string pos位置字符的引用,该函数会自动检测pos位置对于string是否是有效的位置,如果不是有效位置的话就会报异常:

int main()
{
    string str("Test string");

    for (unsigned i = 0; i < str.length(); ++i)
    {
        cout << str.at(i);
    }

    return 0;
}

3.4.3back

在这里插入图片描述
该函数的作用为:返回string中最后一个字符的引用,这个函数不能被调用在空string上,否则会断言报错:

int main()
{

	string str("hello world.");
	str.back() = '!';
	cout << str << '\n';//hello world!

	string s1;
	s1.back();//会断言报错

	return 0;
}

3.4.4front

在这里插入图片描述
该函数的使用和back的使用类似,但是与begin返回迭代器指向不同,front返回的是字符的直接引用,不再展示使用

3.5Modifiers – 修改器

3.5.1operator+= – 重点

在这里插入图片描述
该函数的作用为:在string原来值的基础上,在其末尾追加something,可以是字符、字符串、string引用,同样,\0的位置也会跟着更改:

int main()
{
	string s1("hello world!");
	cout << s1 << endl;

	s1 += 'x';
	cout << s1 << endl;
	s1 += " hello! ";
	cout << s1 << endl;
	string s2("s1");
	s1 += s1;
	cout << s1 << endl;

	return 0;
}

3.5.2append

在这里插入图片描述
该函数的作用为:通过在原字符的基础上追加字符来扩展原来的string:

int main()
{
	string s1("hello!");
	string s2("world!");

	//用法1:追加整个字符串
	s1.append("x");
	s1.append(" world ");
	s1.append(s2);

	//用法2:追加字符串的一部分
	s1.append(s2, 0, 2);//左开右闭

	//用法3:追加数组字符,比如C-string,这个之后说
	//string& append(const char* s);

	//用法4:追加指向s数组的前n个字符的拷贝
	//string& append(const char* s, size_t n);

	//用法5:追加n个字符的拷贝版本
	s1.append(3, 'x');

	//用法6:追加迭代器范围内的一串字符
	s1.append(s2.begin() + 1, s2.end());

	return 0;
}

3.5.3push_back

在这里插入图片描述
该函数的作用为:在string的末尾新增一个字符:

int main()
{
    string str("hello ");
   
    str.push_back('w');
    str.push_back('o');
    str.push_back('r');
    str.push_back('l');
    str.push_back('d');
    cout << str << endl;

    return 0;
}

3.5.4assign

在这里插入图片描述
该函数的作用为:为string分配一个新的值,替代掉它原本的内容,但是它的capacity不变,该函数的使用和之前append的使用很相似,所以就不过多展示

3.5.5insert – 重点

在这里插入图片描述
该函数的作用为:将额外的字符插入到由pos所指的string位置中:

int main()
{
	string s1("hello world");
	string s2("xxxxxxxxxxx");

	//string (1)
	s1.insert(1, s2);
	cout << s1 << endl;// hxxxxxxxxxxxello world

	//buffer (4)
	s1.insert(1, "abc", 1);
	cout << s1 << endl;// haxxxxxxxxxxxello world

	//single character (6)
	string str = "to be question";
	string str3 = "or not to be";
	auto it = str.insert(str.end(), 3, '.');
	cout << str << endl;// to be question...
	str.insert(it + 2, str3.begin(), str3.begin() + 3);
	cout << str << endl;// to be question.. or .

	return 0;
}

3.5.6erase – 重点

在这里插入图片描述
该函数的作用为:删除string的一部分,减少它的size:

int main()
{
    std::string str("This is an example sentence.");
    std::cout << str << '\n';
    // "This is an example sentence."

    str.erase(10, 8);//左开右闭              
    std::cout << str << '\n';
    // "This is an sentence."

    str.erase(str.begin() + 9); 
    std::cout << str << '\n';
    // "This is a sentence."

    str.erase(str.begin() + 5, str.end() - 9); 
    std::cout << str << '\n';
    // "This sentence."

    return 0;
}

3.5.7replace

在这里插入图片描述
该函数的作用为:替换字符串的一部分,左闭右开:

int main()
{
	string base = "this is a test string.";
	string str2 = "n example";
	string str3 = "sample phrase";
	string str4 = "useful.";

	string str = base;           // "this is a test string."
	str.replace(9, 5, str2);          // "this is an example string." (1) 将str从下标9的位置开始的5个字符替换为str2
	str.replace(19, 6, str3, 7, 6);     // "this is an example phrase." (2) 将str从下标19开始的6个字符替换成str3从7开始的6个字符
	str.replace(8, 10, "just a");     // "this is just a phrase."     (3) 将str从8开始之后的10个字符替换
	str.replace(8, 6, "a shorty", 7);  // "this is a short phrase."    (4) 从8开始的6个字符替换
	str.replace(22, 1, 3, '!');        // "this is a short phrase!!!"  (5) 22的一个字符替换为3个!

	str.replace(str.begin(), str.end() - 3, str3);                    // "sample phrase!!!"      (1) //从begin到倒数第三个字符替换
	str.replace(str.begin(), str.begin() + 6, "replace");             // "replace phrase!!!"     (3) //[begin, begin+6)替换
	str.replace(str.begin() + 8, str.begin() + 14, "is coolness", 7);    // "replace is cool!!!"    (4) //左闭右开进行替换,替换为前7个字符
	str.replace(str.begin() + 12, str.end() - 4, 4, 'o');                // "replace is cooool!!!"  (5) //替换为4个o
	str.replace(str.begin() + 11, str.end(), str4.begin(), str4.end());// "replace is useful."    (6) //迭代器范围替换
	std::cout << str << '\n';

	return 0;
}

3.5.8swap

在这里插入图片描述
该函数的作用为:交换string的内容:

int main()
{
	string s1("hello world!");
	string s2("xxxxxxxxxxxxxxxxxxxxxxxxxxxx");

	cout << s1 << endl;
	cout << s2 << endl;
	s1.swap(s2);
	cout << s1 << endl;
	cout << s2 << endl;

	return 0;
}

3.5.9pop_back

在这里插入图片描述
该函数的作用为:删除字符串的最后一个字符,并且使它的size-1:

int main()
{
	string s1("hello world!");

	cout << s1.size() << endl;//12
	s1.pop_back();
	cout << s1.size() << endl;//11

	return 0;
}

3.6String operations – 字符串操作

3.6.1c_str – 重点

在这里插入图片描述
该函数的作用为:获得一个C语言字符串,内容与string内容等效,且字符串末尾会加上\0结尾,因为在某些情况下,string无法发挥出C语言中字符串的意思,所以这里提供了一个转换:

#include <assert.h>
int main()
{
	string filename("test.cpp");
	//在此情况下,只能使用字符串
	FILE* fout = fopen(filename.c_str(), "r");
	assert(fout);

	char ch = fgetc(fout);
	while (ch != EOF)
	{
		cout << ch;
		ch = fgetc(fout);
	}

	return 0;
}

3.6.2data

在这里插入图片描述
该函数与c_str函数类似,不同的是,该函数获得的字符串中不确定是否为\0结尾,该函数不再演示使用

3.6.3copy

在这里插入图片描述
该函数的作用为:从string中pos指向的位置开始,拷贝len个字符到s指向的数组中,函数返回拷贝到数组中的字符数,可能等于len或length-pos:

int main()
{
	char buffer[20];
	string str("Test string...");

	size_t length = str.copy(buffer, 6, 5);
	buffer[length] = '\0';
	cout << "buffer contains: " << buffer << '\n';

	return 0;
}

3.6.4find – 重点

在这里插入图片描述
该函数的作用为:在string中搜索由参数指出的数据的第一次出现位置,如果成功返回下标,如果失败返回npos,即size_t-1,即MAX_INT:

int main()
{
	string s1("hello world!");
	string s2("world");
	string s3("x");

	size_t ret = 0;

	//使用1:从strng中从pos位置找参数string
	ret = s1.find(s2, 6);//能找到,返回6
	ret = s1.find(s2, 7);//未找到,返回18446744073709551615

	//使用2:从string中从pos位置找C语言字符串类型str
	//size_t find(const char* s, size_t pos = 0) const;

	//使用3:从string中从下标pos位置开始查找,查找n个字符,看是否能找到目标字符串s
	ret = s1.find(s2.c_str(), 6, 5);

	//使用4:在string中从pos位置找字符c
	ret = s1.find('c', 0);
	cout << ret << endl;

	return 0;
}

3.6.5rfind – 重点

在这里插入图片描述
与find唯一不同的是,该函数是从后往前找,而且查找时也不尽相同:

int main()
{
	string s1("hello world");
	string s2("world");

	size_t ret = 0;

	//rfind实际上开始的位置为pos+str.size,但是不包括该位置的字符
	ret = s1.rfind(s2, 5);//没有找到,下表为5指向w,+size下标指向d,但不包括d
	cout << ret << endl;
	ret = s1.rfind(s2, 7);//能找到
	cout << ret << endl;

	return 0;
}

3.6.6find_first_of

在这里插入图片描述
该函数的功能为:从一个string1中查找另一个string2中所有存在的字符,成功返回string2中字符最先在string1中找到的位置,不成功返回npos:

int main()
{
	string s1("hello world!");
	string s2("aeiou");

	size_t found = s1.find_first_of(s2);
	while (found != string::npos)
	{
		s1[found] = '*';
		found = s1.find_first_of(s2);
	}
	cout << s1 << endl;//h*ll* w*rld!

	return 0;
}

3.6.7find_last_of

在这里插入图片描述
该函数与find_first_of的使用相同,不同的是,该函数是从右向左进行查找

3.6.8find_first_not_of

在这里插入图片描述
该函数的作用为:查找不在指定字符串中的字符:

int main()
{
	string s1("hello world!");

	size_t found = s1.find_first_not_of("aeiou");
	while (found != string::npos)
	{
		s1[found] = 'o';
		found = s1.find_first_not_of("aeiou");
	}
	cout << s1 << endl;//oeoooooooooo

	return 0;
}

3.6.9find_last_not_of

在这里插入图片描述
同样地,从后边开始查找

3.6.10substr – 重点

在这里插入图片描述
该函数的作用为:获得子串:

int main()
{
	string s1("hello world");

	//获取s1中从下标0位置开始的5个字符
	string s2 = s1.substr(0, 5);
	cout << s2 << endl;// hello

	//获取从下标为1开始,向后的所有字符
	string s3 = s1.substr(1);
	cout << s3 << endl;// ello world

	//获取整个string
	string s4 = s1.substr();
	cout << s4 << endl;// hello world

	return 0;
}

3.6.11compare

在这里插入图片描述
该函数是用来比较string的函数:
在这里插入图片描述

int main()
{
	string s1("hello");
	string s2("hella");

	int ret = s1.compare(s2);
	cout << ret << endl;// 1 > 0,s1 > s2

	return 0;
}

3.7getline

在这里插入图片描述
该函数的作用为:从流中读取一行到string中,但是与cin不同的是,cin遇到空格或换行会默认读取结束,但是getline不会,getline能够读取一行,包括空格,甚至可以自己控制读取结束的条件:

int main()
{
	string name;

	//使用1:不指定结束字符
	cout << "Please, enter your full name: ";
	getline(std::cin, name);//hello world
	cout << name << endl;;//hello world

	//使用2:指定结束符
	getline(cin, name, 'a');
	cout << name << endl;
	return 0;
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2176781.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CSS实现磨砂玻璃效果

引言 最近看到有一种磨砂玻璃背景效果很好看&#xff0c;自己简单制作了一个美杜莎女王小卡片&#xff0c;效果如下&#xff1a; backdrop-filter: blur(10px); 通过设置背景幕布的模糊程度&#xff0c;结合背景图片&#xff0c;实现磨砂玻璃效果 案例代码 <!DOCTYPE h…

探索Kimi:为程序员打造的智能助手

程序员的生活充满了挑战和创新。他们需要快速获取信息、解决问题并保持技术的前沿。在这个快节奏的环境中&#xff0c;一个可靠的智能助手可以成为他们最宝贵的资源之一。今天&#xff0c;我想向你们介绍Kimi——一个由月之暗面科技有限公司开发的人工智能助手&#xff0c;它专…

都选这条赛道,万粉博是不是要烂大街了...

最近参加了一个有意思的项目&#xff1a;视频号数字人直播带货&#xff0c;就是批量起矩阵号发布视频&#xff0c;视频内容呢都是卖各种东西&#xff0c;比如足球灯、除螨喷雾、果蔬净等等。 这是一个比较有潜力的项目&#xff0c;到后面再给大家具体介绍吧。那今天给大家介绍的…

springboot整合sentinel和对feign熔断降级

一、准备 docker安装好sentinel-dashboard&#xff08;sentinel控制台&#xff09;&#xff0c;参考docker安装好各个组件的命令启动sentinel-dashboard&#xff0c;我的虚拟机ip为192.168.200.131&#xff0c;sentinel-dashboard的端口为8858 二、整合sentinel的主要工作 在…

LeetCode讲解篇之53. 最大子数组和

文章目录 题目描述题解思路题解代码 题目描述 题解思路 该问题我们可以转换为求以i为最后一个元素的0 ~ i范围内的最大子数组和&#xff0c;然后其中的所有的最大子数组和的最大值就是我们要返回的答案 题解代码 func maxSubArray(nums []int) int {ans : nums[0]for i : 1;…

PID控制算法(六)

#include <stdio.h> #include <stdlib.h>// 定义PID结构体 typedef struct {float SetSpeed;float ActualSpeed;float err;float integral;float vo_out; //控制器输出float err_last;float Kp;float Ki;float Kd;float limit_min; // 输出限制最小值flo…

基于php的酒店管理系

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏&#xff1a;Java精选实战项目…

毕业设计——小程序项目的完整原型设计

作品详情 完整短剧项目的需求文档&#xff0c;包括小程序项目的完整原型设计&#xff0c;数据指标体系与埋点规划&#xff0c;会员系统、剧集播放解锁、充值支付等逻辑设计。 项目文档链接&#xff1a;https://axhub.im/ax10/b224d75a2ea99a8b/#g1

校园跑腿圈子论坛社团小程序APP需要多少钱

校园跑腿圈子论坛社团小程序APP的开发费用因多种因素而异&#xff0c;包括功能需求、设计需求、开发团队规模和技术难度等。以下是对这些因素的详细分析以及大致的费用估算&#xff1a; 一、功能需求 校园跑腿小程序的基本功能可能包括用户注册登录、任务发布与接单、实时聊天…

gitee公钥设置、创建库及使用

简介 一、如何安装git 使用gitee&#xff0c;需要先安装git工具。 工具网站地址&#xff1a;https://git-scm.com/downloads 安装完成后&#xff0c;在terminal命令行输入git --version可以查看到git的版本。 二、登录gitee 我们先在 gitee上注册账号并登录。gitee官网&#x…

告别“军备竞赛”!L2进入下沉普及周期,谁在领跑本土方案市场?

随着智能驾驶普及进入20万元以下价位区间&#xff0c;“军备竞赛”模式不再成为主流。尤其是成本占比权重更加突出&#xff0c;取消激光雷达、算力降维以及高低配策略&#xff0c;成为「新常态」。 8月27日&#xff0c;小鹏MONA M03正式上市&#xff0c;22天后&#xff0c;新车…

828华为云征文|部署高性能个人博客系统 VanBlog

828华为云征文&#xff5c;部署高性能个人博客系统 VanBlog 一、Flexus云服务器X实例介绍二、Flexus云服务器X实例配置2.1 重置密码2.2 服务器连接2.3 安全组配置2.4 Docker 环境搭建 三、Flexus云服务器X实例部署 VanBlog3.1 VanBlog 介绍3.2 VanBlog 部署3.3 VanBlog 使用 四…

中腾国际团餐产业集团经验谈:如何让上海央厨配送更高效、更安心

上海作为国际大都市&#xff0c;近些年对餐饮行业的效率与品质提出了更高要求。中央厨房(央厨)以其规模化、标准化生产的优势&#xff0c;成为提升餐饮供应链效率的关键一环。而央厨配送&#xff0c;作为连接央厨与消费者的重要桥梁&#xff0c;其重要性不言而喻。中腾国际团餐…

2024年双十一值得入手好物?2024年双十一必买清单!

双十一的号角已经吹响&#xff0c;你是否还在为买什么而纠结&#xff1f;快来看看这份2024年双十一必买清单&#xff01;这里汇聚了各类令人惊喜的好物&#xff0c;从科技新宠到生活必备&#xff0c;总有一款能打动你的心&#xff01; 一、真1000w配置——西圣find可视挖耳勺 …

实在智能:创业需找准“切口” 并着力做深做透

如今&#xff0c;随着人工智能产业的爆发&#xff0c;大量专注于这一领域的初创企业不断涌现。尽管这种多元化的创新生态为产业发展注入了新的活力&#xff0c;但也不可避免的为初创企业带来了诸多压力和挑战。 浙江实在智能科技有限公司(以下简称“实在智能”)作为一家成立6年…

大模型开发 - 一文搞懂Fine-tuning(大模型微调)

本文将从Fine-tuning的本质、Fine-tuning的原理Fine-tuning的应用三个方面&#xff0c;带您一文搞懂大模型微调&#xff1a;Fine-tuning Fine-tuning&#xff08;微调&#xff09;&#xff1a;通过特定领域数据对预训练模型进行针对性优化&#xff0c;以提升其在特定任务上的性…

别人做谷歌seo凭什么比你好?

谷歌SEO的竞争激烈&#xff0c;做得好的才能占据排名。但为什么有些人做SEO就是比你好&#xff1f;其中一个关键因素就是资源投入。SEO的核心包括技术优化、内容质量和外链建设等。这些方面都需要专业知识和时间投入&#xff0c;但如果资源有限&#xff0c;你的优化效果就会受到…

NVM:nvm list available命令执行异常

一、异常图片 二、解决 在nvm的安装位置找到文件settings.txt&#xff0c;修改镜像地址 node_mirror: https://npmmirror.com/mirrors/node/ npm_mirror: https://npmmirror.com/mirrors/npm/ 再次执行 三、相关知识 3.1 nvm简介 NVM&#xff08;Node Version Manager&#…

huggingface使用国内镜像站下载

huggingface使用国内镜像站下载 huggingface开源的模型托管仓库&#xff0c;预训练模型的数量已超过30万个&#xff0c;并且任何模型在下载之前都可以使用huggingface提供的spaces空间去测试效果 huggingface的国内镜像站HF-Mirror的地址&#xff1a;https://hf-mirror.com/ …

聊聊JIT是如何影响JVM性能的!

文章内容收录到个人网站&#xff0c;方便阅读&#xff1a;http://hardyfish.top/ 文章内容收录到个人网站&#xff0c;方便阅读&#xff1a;http://hardyfish.top/ 文章内容收录到个人网站&#xff0c;方便阅读&#xff1a;http://hardyfish.top/ 我们知道Java虚拟机栈是线程…