【C++】string类(接口使用详解 下)

我们接着【C++】string类(接口使用详解 上)-CSDN博客 继续介绍string的使用。

1.string类对象的修改操作

我们就说一下用的比较多的接口。

1.1 operator+=

这个接口可以尾插一个字符,或者一个字符串,或者一个对象。

复制代码
string s1("hello world!");
string s2("qqqqqqq");
s1 += 'x';  // 尾插一个字符
s1 += "yyyyy"; //尾插一个字符串
s1 += s2; //尾插一个对象
cout << s1 << endl;

在实践中直接用这个接口尾插就行。

1.2 append和 push_back

这两个接口也是尾插的,了解一下即可,我们一般就用前面介绍的operator+=。

push_back是尾插一个字符。

append是尾插一个字符串,对象,对象的一部分等等,详细的看文档。

复制代码
string s1("hello world!");
s1.push_back('q'); //尾插一个字符
s1.append("xxxxxx"); //尾插字符串

常用的用法就是上面这样,append的其他接口基本不咋用。

1.3 insert

这是插入数据的接口,提供了7个,不过大部分用的不多。

常用的用法就两个,用这个头插,或者字符串中间位置插入数据。其他接口用的不多。

复制代码
string s1("hello world!");
cout << s1 << endl;
s1.insert(0, 2, 'a'); //在下标为0的位置开始插入2个a
cout << s1 << endl;
复制代码
string s1("hello world!");
cout << s1 << endl;
s1.insert(0, 2, 'a'); 
cout << s1 << endl;
s1.insert(8, 4, 'x');
cout << s1 << endl;

但是头插和中间插入的使用需谨慎,我们学过顺序表可以知道,头插或者中间插入需要把后面的数据都往后移动,如果空间不够还要扩容。

在使用这些接口的时候,不确定用法就看文档介绍。

1.4 erase

erase是用来删除数据的。

在实践中用的最多的还是第一个接口:从pos的位置开始删除npos个数据。

复制代码
    string s1("hello world");
	s1.erase(6, 1); //从下标为6的位置,删除1个数据
	cout << s1 << endl; 

如果我们要头删,如下。

复制代码
   	s1.erase(0, 1); //头删 
	cout << s1 << endl;

这个接口的npos也是缺省参数,pos位置后面字符剩多少就是多少 。

如果我们想把pos位置之后的全删了,第二个参数可以不传,就用npos的缺省值。

复制代码
	string s1("hello world");
	s1.erase(6); //从6的位置开始后面全删除 
	cout << s1 << endl;

还提供了一个迭代器的版本,就是(3).

用迭代器版本头删也可以。

复制代码
s1.erase(s1.begin()); //迭代器版头删 
cout << s1 << endl;

用迭代器版本尾删也可以。

复制代码
s1.erase(--s1.end()); //迭代器版尾删 
cout << s1 << endl;

注意 括号里是s1.end()的前置减减,因为end()返回的是最后一个字符的下一位,减减end()才是返回最后一个字符。

复制代码
//迭代器版尾删另一种写法
s1.erase(s1.size()-1, 1); 

1.5 replace

replace就是替换,它提供的接口也是非常多。

大概就是我们可以把pos位置开始的len个字符替换字符串、字符串的一部分,对象,对象的一部分,迭代器,迭代器的一部分。来简单运用一下。

少被替换多

复制代码
string s1("hello world");
//把5位置开始的1个字符替换成2个%
s1.replace(5, 1, "%%");
cout << s1 << endl;

多被替换少

复制代码
string s1("hello world");
s1.replace(5, 1, "%%");
cout << s1 << endl;
//把0开始的4个字符替换成3个x	
s1.replace(0, 4, "xxx");
cout << s1 << endl;

等大小替换

复制代码
	s1.replace(0, 3, "yyy");
	cout << s1 << endl;

1.6 swap和pop_back

一个是交换,一个是尾删,了解一下即可。

string的其他接口在这就不一一介绍了,大家在使用的时候不清楚的话查一下文档就好了。

2.find系列接口

2.1 find

从pos位置查找字符,字符串,对象,返回值是size_t类型。

如果找到了,返回找到的第一个目标的下标位置。 如果没找到,返回npos。

举个例子。

复制代码
string s2("hello world hello csdn");
size_t pos = s2.find(" "); //找空格

如果我们找到空格,把空格全部换成%%。

复制代码
size_t pos = s2.find(" "); //找空格,把下标存在pos里 
while (pos != string::npos) 
{
	s2.replace(pos, 1, "%%"); //替换 
	pos = s2.find(" "); //找下一个空格 
}
cout << s2 << endl; 

但是这样写的话,我们不给第二个参数传参,find每次都要从头找,很麻烦,我们给第二个参数传参,可以从指定位置开始找。把while循环里面的第二条语句改一下。

复制代码
while (pos != string::npos) 
{
	s2.replace(pos, 1, "%%"); //替换 
	pos = s2.find(" ", pos + 2); //pos+2位置开始找下一个空格 
}

这里第二个参数是pos+2,是因为我们把空格这一个字符替换成了两个%。结果是一样的。

2.2 rfind 和substr

rfind和find差不多,只不过rfind是倒着找。

substr是把pos位置的len个字符拿出来拷贝到新的string里,这里npos是老朋友了,如果npos不给值,就是拷贝到结尾。返回值类型是string。

rfind和substr结合起来用,可以用在找文件的后缀。

复制代码
//假设文件是string.cpp
string s3("string.cpp");  
size_t pos = s3.rfind('.'); //从后开始找. 
string suffix = s3.substr(pos); //找到后把后缀存到suffix里 
cout << suffix << endl;
复制代码
//假设文件是string.cpp.zip
string s3("string.cpp.zip");  
size_t pos = s3.rfind('.'); //从后开始找. 
string suffix = s3.substr(pos); //找到后把后缀存到suffix里 
cout << suffix << endl;

2.3 find_first_of

名字看起来是找第一个,其实并不是,别被名字迷惑哦。

find_first_of 是找任意一个字符,举个例子,如下。

复制代码
string str ("Please, replace the vowels in this sentence by asterisks.");
cout << str << '\n';
size_t found = str.find_first_of("abcd");//找abcd的任意一个,a或者b或者c或者d 
while (found!=string::npos)
{
  str[found]='*';  //只要是a或者b或者c或者d都会被替换成* 
  found=str.find_first_of("abcd",found+1);
}
cout << str << '\n';

大家一定不能被名字迷惑!是传的任意一个字符都会被找到!

从下面这句代码也可以看出,第二个参数是从pos位置开始找,不传默认为0位置开始。

复制代码
found=str.find_first_of("abcd",found+1);

2.4 find_last_of

这个函数和find_first_of 功能是一样的,只不过是从后面往前找。

举个例子,还是用文件举例。假设我们要把文件路径和文件名分隔开看,Windows和Linux下的文件分隔符不一样,Windows下是\,Linux下是/,代码如下。

复制代码
void SplitFilename (const std::string& str)
{
  cout << "Splitting: " << str << '\n';
  size_t found = str.find_last_of("/\\");//从后往前,找/和\\的任意一个 
  cout << " path: " << str.substr(0,found) << '\n';
  cout << " file: " << str.substr(found+1) << '\n';
}

int main ()
{
  string str1 ("/usr/bin/man"); //Linux路径 
  string str2 ("c:\\windows\\winhelp.exe");//Windows路径 

  SplitFilename (str1);
  SplitFilename (str2);

  return 0;
}

2.5 find_first_not_of和find_last_not_of

这两个和find_first_of、find_last_of相反,比如说前面我们要把是abcd任意一个的找到,这两个接口就是把不是abcd任意一个都找到。

那我们还是拿前面的abcd举例吧,这次换成abcdef。

复制代码
string str ("Please, replace the vowels in this sentence by asterisks.");
cout << str << '\n';
size_t found = str.find_first_not_of("abcdef");//找不是abcdef的任意一个
while (found!=string::npos)
{
  str[found]='*';  //除了abcdef,其它都会被替换成* 
  found=str.find_first_of("abcdef",found+1);
}
cout << str << '\n';

除了abcdef,其它都被替换成*了。

find_last_not_of是一样的,只是从后往前找。

3.string类的非成员函数

3.1 operator+

这个函数为什么没有写成成员函数,而是重载成全局的呢?因为它主要想支持字符串+string的功能。如下。

复制代码
	string s4("hello");
	string s5 = s4 + "world";//string+字符串
	cout << s5 << endl; 
	string s6 = "world" + s4;//字符串+string 
	cout << s6 << endl;

我们说过重载运算符,二元的,两个操作数左右顺序一一对应,如果是成员函数,左操作数只能是string,重载成全局的函数,就可以支持字符串是左操作数。

3.2 比较大小

比较大小的接口也是重载了一大堆,在这里就不说了 。

3.3 <<、>>、 swap

swap留到后面再说,流插入和流提取也没啥说的~

3.4 getline

cin和scanf默认我们输入空格或者换行符就停止一个输入,如果我们要输入hello world,输入到str里,str只会存hello进去,world会认为是另一个对象的。

我们用getline输入的话,第一个参数传cin,第二个参数传对象,第三个参数不传,默认以换行符未结束标志。

第三个参数传的话,传什么,就以什么为结束标志。

string的其他接口在这就不一一介绍了,大家在使用的时候不清楚的话查一下文档就好了。

到这string的使用就全部说完了,拜拜~

相关推荐
龙湾开发2 分钟前
计算机图形学编程(使用OpenGL和C++)(第2版)学习笔记 10.增强表面细节(二)法线贴图
c++·笔记·学习·图形渲染·贴图
whoarethenext12 分钟前
c/c++的opencv的轮廓匹配初识
c语言·c++·opencv
爱吃涮毛肚的肥肥(暂时吃不了版)13 分钟前
项目班——0510——JSON网络封装
c++·算法·json
isyangli_blog21 分钟前
(1-4)Java Object类、Final、注解、设计模式、抽象类、接口、内部类
java·开发语言
apocelipes24 分钟前
使用libdivide加速整数除法运算
c语言·c++·性能优化·linux编程
三块钱079429 分钟前
【原创】基于视觉大模型gemma-3-4b实现短视频自动识别内容并生成解说文案
开发语言·python·音视频
虾球xz29 分钟前
游戏引擎学习第290天:完成分离渲染
c++·人工智能·学习·游戏引擎
易只轻松熊29 分钟前
C++(20): 文件输入输出库 —— <fstream>
开发语言·c++·算法
虾球xz31 分钟前
游戏引擎学习第285天:“Traversables 的事务性占用”
c++·学习·游戏引擎
芯眼32 分钟前
ALIENTEK精英STM32F103开发板 实验0测试程序详解
开发语言·c++·stm32·单片机·嵌入式硬件·社交电子