【C++21天养成计划】字符串——快速上手STL string类(Day15)

大家好!我是【AI 菌】,一枚爱弹吉他的程序员。我热爱AI、热爱分享、热爱开源! 这博客是我对学习的一点总结与思考。如果您也对 深度学习、机器视觉、算法、Python、C++ 感兴趣,可以关注我的动态,我们一起学习,一起进步~
我的博客地址为:【AI 菌】的博客
我的Github项目地址是:【AI 菌】的Github


一、string类的使用优点

在C++中,字符串是一个字符数组。最简单的字符数组数组可这样定义:

char staticArray[20]; //声明一个固定长度的静态字符数组

这样的一个静态数组,它的长度是固定的。而在很多实际问题中,我们定义的字符数组长度事先是不能确定的,因此我们希望能声明一个动态字符数组,按照程序需要动态调整数组长度。

string类就给我们提供了这样的一个捷径,它不仅能够根据程序的需求动态调整大小,还提供了很多有用的成员函数(方法),帮助更加方便地操作字符串。

在这里插入图片描述

二、string类的基本操作

2.1 六种初始化方法

string类提供了很多重载的构造函数,因此可以使用多种方式进行初始化和实例化。下面一共举例了最常用的6种方法:

#include <iostream>
#include <string>
using namespace std;

int main()
{	
	//1.初始化方法1
	string str1 = "Study String!"; //初始化一个字符串
	//2.初始化方法2
	string str2("Study String!"); //初始化,实质是调用string类的重载的构造函数进行初始化
	//3.初始化方法3
	string str3(str1);  //将str3复制到str1
	//4.初始化方法4
	string str4(6,'A'); //输出6个A 
	//5.初始化方法5
	string str5(str1, 6, 6); //输出String,从str1的第6个位置起取连续6个字符
	//6.初始化方法6
	string str6(str1.begin(), str1.begin()+5); //输出Study,取str1的前5个字符
	//最后可以全部打印出来看看
	cout<<str1<<endl<<str2<<endl<<str3<<endl<<str4<<endl<<str5<<endl<<str6<<endl;
	return 0; 
}

2.2 四种基本容量

string类提供了9种capacity,也就是常说的容量,我们最常用到的有以下4种:size、length、capacity 和 empty。下面来分别介绍以下它们的功能:

函数 功能
size 返回字符串的长度
length 返回字符串的长度
capacity 返回字符串允许存放字符的最大长度(容量)
empty 判断字符串是否为空,返回一个布尔值。

注:所谓容量,可以理解为字符串的长度、所占内存容量大小等属性。

下面就实际演示一下以上4种容量,来看一下它们的区别:

#include<iostream>
#include<string>
using namespace std;

int main()
{
	string str1="Hello String!";
	
	cout<<"size="<<str1.size()<<endl;
	cout<<"length="<<str1.length()<<endl;
	cout<<"capacity="<<str1.capacity()<<endl;
	if(str1.empty())
		cout<<"字符串str1是空的!";
	else
		cout<<"字符串str1不是空字符串!"; 
	return 0; 
} 

2.3 三种访问字符串内容方法

要访问string类的字符内容,可以使用以下三种方法:

  1. 采用类似于数组的语法,使用下标运算符[ ]。
  2. 使用迭代器。
  3. 使用操作函数at()。

下面就使用以上 3 种方法,来实地操作一波:

#include <iostream>
#include <string>
using namespace std;

int main()
{	
	string s1("Good night!");
	
	//方法1:采用[],类似数组的方法 
	cout<<"显示字符串s1中的各个内容:"<<endl;
	for(int i=0; i<s1.length(); i++)
	{
		cout<<"s1["<<i<<"] is: "<<s1[i]<<endl;
	}
	cout<<endl;
	
	//方法2:采用迭代器的方法 
	cout<<"显示字符串s1中的各个内容:"<<endl;
	int charOffset=0;
	string::const_iterator Locator;
	for(Locator=s1.begin(); Locator!=s1.end(); ++Locator) 
	{
		cout<<"s1["<<charOffset++<<"] is: "<<*Locator<<endl;
	}
	cout<<endl;
	
	//方法3:采用操作函数at()
	cout<<"显示字符串s1中的各个内容:"<<endl;
	for(int i=0; i<s1.length(); i++)
	{
		cout<<"s1["<<i<<"] is: "<<s1.at(i)<<endl;
	}
	
	return 0;
}

三、string类的基本函数

基本的字符串函数包括:拼接、新增、删除、反转 等。使用这些字符串函数,能够轻松的解决很多字符串操作问题,并且使你的代码变得更加简洁可读。下面就来分别来讲一讲这些基本的操作函数!

3.1 拼接字符串append()

要将两个字符串拼接在一起,可以使用 运算符+=,也可以使用成员函数append():

#include<iostream>
#include<string>
using namespace std;

int main()
{
	string s1("I love");
	string s2(" you!");
	
	//方法1:+=
	s1+=s2;
	cout<<s1<<endl;
	
	//方法2:append()
	string s3(" I love you very much!");
	s1.append(s3);
	cout<<s1<<endl;
	return 0;
} 

3.2 末尾新增字符push_back()

使用push_back(),我们可以在原字符串末尾新增字符。下面是一个有趣的例子,可以将test.txt文件中的字符一个个的写入字符串str。

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main ()
{
  string str;
  ifstream file ("test.txt", ios::in);
  if (file) 
  {
    while (!file.eof()) 
    	str.push_back(file.get());
  }
  cout << str << '\n';
  return 0;
}

注:如果你想更方便地在字符串末尾进行新增操作,可以使用append,它不仅可以新增一个字符,还能一次新增一个字符串。

3.3 末尾删除字符pop_back()

使用pop_back(),我们可以在原字符串后删除一个字符,这与前面讲到的STL list类和STL vector类中的用法也是一样的。

#include <iostream>
#include <string>
using namespace std;

int main()
{	
	string s1("Good night!");
	
	s1.pop_back();
	
	cout<<"s1="<<s1<<endl;
	
	return 0;
}

3.4 字符串反转reverse()

所谓反转,就是首尾倒序存放。比如要判断某字符串是否是回文串,就可以将其反转,再与原来的字符串进行比较。

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;

int main()
{
	string s1("I love you!");
	reverse(s1.begin(),s1.end());  //将s1进行反转
	cout<<s1;
	return 0;
} 

四、string类的进阶函数

除了基础的几种字符串函数外,string类还提供了几种常用的字符串操作函数:查找字符、截短、大小写转换、子字符串、字符串比较 等。使用好这些进阶的字符串函数,往往能够题使代码简化,达到 事半功倍 的效果!

4.1 查找字符或者子字符串find()

string类的成员函数find,可以用来查找字符串中的字符子字符串,比如:

//从索引为n的位置开始,查找字符串s1中的子串s2,并返回给pos。(其中,s2可以是字符也可以是子字符串)
int pos=s1.find(s2,n);
#include<iostream>
#include<string>
using namespace std;

int main()
{
	string s1("I love you! and do you love me?");
	cout<<"s1:"<<s1<<endl;
	
	//1.从最开始处开始搜索,返回字符串love第一次出现的位置 
	size_t position= s1.find("love",0);
	if(position!=string::npos) //string:npos实际值为-1,表示没有找到要搜索的元素
		cout<<"字符串love第一次出现的位置:"<<position<<endl;
	else
		cout<<"字符串love没有被找到"<<endl; 
		
	//2.返回所有子字符串的位置
	cout<<"字符串love出现的所有位置:"; 
	size_t all_pos=s1.find("love",0);
	while(all_pos!=string::npos)
	{
		cout<<all_pos<<" ";
		size_t  search_pos=all_pos+1;
		all_pos=s1.find("love",search_pos); //返回子字符串出现的位置 
	} 
	return 0;
} 

4.2 截短字符串erase()

截短字符串函数erase(),有以下三种常用的方法:

(1)给定偏移位置(删除的起始位置)和要删除的字符个数。

string s1 = "I love you very much!"
s1.erase(2,4); //从索引号2开始,删除4个字符,即删掉love。

(2)在给定指向字符的迭代器时删除该字符

//删除字符串s1中的所有的字符'I'
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;

int main()
{
	string s1("I love you! and do you love me?");
	string::iterator pos = find(s1.begin(),s1.end(),'I'); //找到字符'I'的位置给迭代器
	if(pos!=s1.end())
		s1.erase(pos); //依次删除迭代器指向的字符
	cout<<s1<<endl;
	return 0;
} 

(3)在给定两个迭代器指定的范围时,删除该范围内的字符

s1.erase(s1.begin(),s1.end());

4.3 大小写转换transform()

使用大小写转换函数transform(),能够轻松的实现字符串的大小写转换。

//1.将字符串s1转换为大写
transform(s1.begin(),s1.end(),s1.begin(),toupper);
//2.将字符串s1转化为小写
transform(s1.begin(),s1.end(),s1.begin(),tolower);

4.4 子字符串substr()

使用substr(),可以方便地获取字符串的任意子串。substr()函数的声明如下:

string substr (size_t pos = 0, size_t len = npos)

第一个参数是,待获取的子串的起始位置;默认为0,即首字符。
第二个参数是,待获取子串的长度;默认npos,即一直取到末尾。

下面举一个例子,来实际感受一下substr()的用法:

#include <iostream>
#include <string>
using namespace std;

int main ()
{
  string str="We think in generalities, but we live in details.";
                                         
  string str2 = str.substr (3,5);     //str2 = think

  size_t pos = str.find("live");      // position of "live" in str

  string str3 = str.substr (pos);     // get from "live" to the end

  cout << str2 << ' ' << str3 <<endl;

  return 0;
}

运行结果:

think live in details.

4.5 字符串比较compare()

使用compare(),我们可以轻松地对两个字符串进行比较。以 str1.compare(str2) 为例,比较规则 如下表所示:

函数返回值 逐个字符比较 str1 与 str2
=0 str1=str2
<0 str1的第一个不匹配的字符的值较小,或者所有比较的字符都匹配,但 str1 比 str2 更短
>0 str1的第一个不匹配的字符的值较大,或者所有比较的字符都匹配,但 str1 比 str2 更长

注:你可能对这个表还是不太清楚,没关系。你可以这样简单理解,字符串大小比较规则 就是:从左往右,依次比较每个字符对应的ASCII码值,大者为大,小者为小;若相等,则继续比较后面的字符。

理解了字符串比较函数后,我们就来实际操作一波:

#include<iostream>
#include<string>
using namespace std;

int main()
{
	string str1 = "Hello World!";
	string str2 = "Hello String!";
	
	//用法1:比较str1与str2 
	if(str1.compare(str2)==0)
		cout<<"str1=str2"<<endl;
	else if(str1.compare(str2)<0)
		cout<<"str1<str2"<<endl;
	else
		cout<<"str1>str2"<<endl;
	
	//用法2:取str1的第6个位置后的5个字符World与字符串World比较 
	if(str1.compare(6,5,"World")==0)
		cout<<"相等"<<endl;
	else
		cout<<"不等"<<endl;
		
	//用法3:截取两个字符串各自的子串进行比较
	if(str1.compare(0,5,str2,0,5)==0)
		cout<<"str1的子串Hello = str2的子串Hello"<<endl;
	else
		cout<<"str1的子串Hello != str2的子串Hello"<<endl;
		
	return 0;	
} 

运行结果:
在这里插入图片描述


好啦,今天的内容就到这里了!如果这篇博客有帮助到你,记得伸个小手,点个赞哦,您你的支持是我创作的最大动力!

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/wjinjie/article/details/108430209
今日推荐