嗨~大家好,这里是春栀怡铃声的博客~

“做你害怕的事,然后发现,不过如此~”

今天我们就开始学习string !

目录

常见的string 定义字符串

auto关键字

范围for

迭代器

size

capacity

operator+=

reserve

clear

empty

operator[]

​编辑

append

push_back

insert

​编辑

erase

replace

​编辑

swap

pop_back

c_str

find

rfind

substr

查找字符位置的函数

find_first_of 

find_last_of

find_first_not_of

find_last_not_of


在使用string类时,必须包含#include头文件以及using namespace std;

在学习string 类时,通过查找文档进行学习是很好的方法

文档地址:https://legacy.cplusplus.com/reference/string/string/

常见的string 定义字符串

    string s1;                         // 构造空的string类对象s1
    string s2("hello world");   // 用C格式字符串构造string类对象s2
    string s3(s2);                  // 拷贝构造s3

auto关键字

auto声明的变量必须由编译器在编译时期推导而得
用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则必须加&

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

auto a=4;//这里通过4推导出a的类型是int

范围for

范围for由2部分组成,冒号前面是范围内用于迭代的变量,第二变量则表示被迭代的范围

自动读取数据,自动结束

for(auto &ch:s1)

{

    cout<<ch;

}

cout<<endl;

范围for加引用,表示可以修改s1中的值。不加的话,s1中的值不变。

for(auto &ch:s1)

{

    ch-=2;    //这一步可以实现s1中每个值都减2

    cout<<ch;

}

cout<<endl;

通过范围for可以访问字符串,那还有什么其他方法呢?

1.下标 + []

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

// 1、下标 + []
for (size_t i = 0; i < s2.size(); i++)
{
    cout << s2[i] << " ";
}
cout << endl;

迭代器

string 的 iterator 本质上就是“指向字符串中某个字符的位置”的对象。

可以把它理解成一个“更安全、标准化的指针”(注意不是真的指针),专门用来遍历 string 里的字符。

1. 什么是 string::iterator

  对于:

  std::string s = "hello";

  s 内部保存了 5 个字符:h e l l o

  如果定义:std::string::iterator it = s.begin();

  那么 it 就指向第一个字符 'h'。

  它的作用主要是:

  - 遍历字符串
  - 访问某个位置的字符
  - 修改字符内容
  - 配合标准算法使用

利用iterator 访问 string

string::iterator it = s2.begin();
while (it != s2.end())
{
	*it += 2;

	cout << *it << " ";
	++it;
}
cout << endl;

cout << s2 << endl;

iterator 是string 类中的,使用时需要表明是从string 中提取的

begin()

返回指向第一个字符的迭代器。

end()

返回指向“最后一个字符后面”的位置。

注意:end() 不指向有效字符,不能解引用。

std::string s = "abc";

auto it1 = s.begin(); // 指向 'a'
auto it2 = s.end();   // 指向 'c' 后面那个位置

it 当作指针使用,逐个访问字符串中的数据

const 修饰的 迭代器

	string::const_iterator cit = s1.cbegin();
	while (cit != s1.cend())
	{
		cout << *cit << ' ';
		cit++;
	}
	cout << endl;

反向迭代器

	//4.反向迭代器
	string::reverse_iterator rit = s2.rbegin();
	while (rit != s2.rend())
	{
		cout << *rit << " ";
		++rit;
	}
	cout << endl;

 string s = "abc";

  - s.begin() 指向 'a'
  - s.end() 指向 'c' 后面的位置
  - s.rbegin() 指向 'c'
  - s.rend() 指向 'a' 前面的位置

const 修饰的 反向迭代器

	string::const_reverse_iterator crit = s1.crbegin();
	while (crit != s1.crend())
	{
		cout << *crit << ' ';
		crit++;
	}
	cout << endl;

加上const 后,s1中的数据不允许被修改,其他并不改变

size

返回的是s1的有效数据个数

使用

s1.size();

capacity

返回的是s1的空间大小

s1.capacity();

operator+=

向s1末尾添加1个字符、字符串

string s1;
s1+="hello world";
s1+='c';

reserve

提前开好空间

像下面的示例:创建了string 类 的tmp ,想让tmp 拥有和s1一样大的空间存放数据

使用reserve 开出空间

    string tmp;
    tmp.reserve(s1.size());

clear

作用是将s1中数据清除

s1.clear();

empty

返回s1是否为空的判断值,是空返回true ,不是空返回false

operator[]

这个的作用是,现在有一个字符串string s1("hello world")  ,可以通过类似数组下标访问的方式访问字符串中的每个字符

string s1("hello world");

cout<<s1[6]<<endl;

append

使用 append,在s1末尾插入 一段字符串

string s1;    

s.append("yyyyyy");

push_back

使用push_back 在s1末尾插入字符

string s1;    

s.push_back('x');

insert

insert 随便位置插入

    string s("hello world");  

    s.insert(0, "hello ");  //头插
    cout << s << endl;

    s.insert(10, "zzzz"); //在指定位置插入
    cout << s << endl;
 

insert 头插

    s.insert(0, "px");
    cout << s << endl;

    char ch = 't';
    s.insert(s.begin(), ch);

insert 插入

    char ch = 't';
    s.insert(0, 1, ch);

	string s("hello world");

	s.insert(0, "hello ");
	cout << s << endl;

	s.insert(10, "zzzz");
	cout << s << endl;

	s.insert(0, "px");
	cout << s << endl;

	char ch = 't';
	s.insert(0, 1, ch);
	s.insert(s.begin(), ch);

	cout << s << endl;

erase

调用erase,第一个参数是 想要删除位置 的下标,第二个参数是删除的个数  从下标往后数,然后删除 

	string s("hello world");
	s.erase(6, 1);
	cout << s << endl;


	s.erase(0, 1);
	cout << s << endl;

	s.erase(s.begin());
	cout << s << endl;

	s.erase(--s.end());
	cout << s << endl;

	s.erase(s.size() - 1, 1);
	cout << s << endl;

	string ss("hello world");
	ss.erase(6);
	cout << ss << endl;

只有一个参数的erase ,代表从这个参数的下标开始,删除之后所有的字符

replace

string sss("hello                 world hello bit");

sss.replace(5, 1, "%%");
cout << sss << endl;

replace 的第一个参数代表下标,第二个参数代表置换原字符串的占位长度,最后一个参数是置换的字符

swap


  调用 a.swap(b) 后:

  - a 变成原来 b 的内容
  - b 变成原来 a 的内容

 写法:

  s1.swap(s2);

pop_back

含义是:删除字符串最后一个字符。

  例如:

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

  int main() {
      string s = "hello";
      s.pop_back();

      cout << s << endl;   // hell
  }

  调用后,最后一个字符 'o' 被删掉了。

作用

  它常用于:

  - 删除末尾字符
  - 处理多余的分隔符
  - 模拟“退格”效果
  - 配合循环不断缩短字符串

例子 1:删掉最后一个字符

  string s = "abcde";
  s.pop_back();
  cout << s << endl;   // abcd

例子 2:去掉末尾多余逗号

  string s = "a,b,c,";
  s.pop_back();
  cout << s << endl;   // a,b,c

注意

  pop_back() 不返回被删除的字符,它只是直接删掉最后一个字符。

  如果你想先取出最后一个字符再删除,可以这样写:

  char ch = s.back();
  s.pop_back();

还要注意

  字符串不能为空,否则不能随便调用:

  if (!s.empty()) {
      s.pop_back();
  }

  因为对空字符串调用 pop_back() 是不安全的。

  对比一下

  - back():查看最后一个字符
  - pop_back():删除最后一个字符

c_str

返回指向s1这个字符串的指针

find

写法1.  find 查找 特定字符——从sss的首个字符开始寻找。 

size_t pos = sss.find(' ');

写法2.  find 查找 特定字符——从find 的第二个参数位置开始寻找。 

    size_t po = sss.find(' ',pos+2);

将上面所学的replace 和 find 结合 ,你可以试着解决一下这道题

string sss("hello                 world hello bit");

将sss中的空格全部替换为 "%%",一个空格换  "%%"

string sss("hello                 world hello bit");

size_t pos = sss.find(' ');
while (pos != string::npos)
{
	sss.replace(pos, 1, "%%");

	pos = sss.find(' ', pos + 2);


}
cout << sss << endl;

替换过程如下:

先找到第一个空格位置,将空格换为 "%%" ,继续找下一个空格位置,交换  ;

应使用while循环,,pos 不等于npos (字符串末尾)

解决这道题还有一种方案

创建一个新的 string 类 tmp ,  利用reserve 开好和sss 一样大的空间,,利用  for(auto ch :sss)

遍历整个 sss ,如果ch==" "   那就在 tmp 插入 "%%"

如果不等于空格,直接在 tmp 上插入 ch 

交换sss 与tmp 即可

	//更优解
	string tmp;
	tmp.reserve(sss.size());
	for (auto ch : sss)
	{
		if (ch == ' ')
			tmp += "%%";
		else
			tmp += ch;
	}
	cout << tmp << endl;
	sss.swap(tmp);
	cout << sss << endl;

rfind

rfind 和 find 的作用类似,不过 rfind 是从后往前找,

    string s("test.cpp.zip");
    size_t pos = s.rfind('.');

substr

 substr 的作用是:从一个字符串中截取出子串。

 基本用法

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

  含义:

  - pos:从哪个下标开始截取
  - len:截取多少个字符
  - 返回值:一个新的 string

示例:

string s("test.cpp.zip");
size_t pos = s.rfind('.');
string suffix = s.substr(pos);
cout << suffix << endl;

这里substr 没有第二个参数意味着直接从 pos 开始 一直截取到末尾,最后形成新的string 类

查找字符位置的函数

它们都是 std::string 用来查找字符位置的函数。注意:它们查找的是“某个字符集合中的字符”,不是查找整个子串。 

find_first_of
 

从左往右找,返回第一个属于指定字符集合的字符位置。

例子

  string s = "hello world";
  cout << s.find_first_of("aeiou") << endl;

 结果:1

 因为 "hello world" 中从左往右,第一个元音字母是 'e',下标是 1。

find_last_of

从右往左找,返回最后一个属于指定字符集合的字符位置。

 例子

  string s = "hello world";
  cout << s.find_last_of("aeiou") << endl;

  结果:7

  因为从整个字符串看,最后一个元音字母是 'o',位置是 7。

find_first_not_of

含义

  从左往右找,返回第一个不属于指定字符集合的字符位置。

 例子

  string s = "   hello";
  cout << s.find_first_not_of(" ") << endl;

  结果:3

  因为前 3 个都是空格,第一个不是空格的是 'h',位置是 3。

find_last_not_of

 含义

  从右往左找,返回最后一个不属于指定字符集合的字符位置。

  例子

  string s = "hello   ";
  cout << s.find_last_not_of(" ") << endl;

  结果:4

  因为最后一个不是空格的字符是 'o',位置是 4。
 

更多推荐