【C++】C++ STL 探索:String的使用与理解(二)

简介: 【C++】C++ STL 探索:String的使用与理解

【C++】C++ STL 探索:String的使用与理解(一)https://developer.aliyun.com/article/1617331


四、string类对象的访问

关于string类对象的访问,关键掌握operator[]就行。剩下三个不如operator[]好用,其中front、back是为了规范性才实现的。

4.1 operator[]

int main()
{
  string str1("hello world");
  for (int i=0;i<str1.size();i++)
  {
    //cout << str1.operator[](i) << endl;
    cout << str1[i] << endl;
  }
  const string str2("hello world");
  for (int i = 0; i < str2.size(); i++)
  {
    //str2[i]++; const修饰的话,没有修改的权限
    cout << str2[i] << endl;
  }
  return 0;
}

五、string类对象的遍历操作

函数名称 功能说明
operator[] (重 点) 返回pos位置的字符,const string类对象调用
begin+ end begin获取一个字符的迭代器 + end获取最后一个字符下一个位置的迭 代器
rbegin + rend begin获取一个字符的迭代器 + end获取最后一个字符下一个位置的迭 代器
范围for C++11支持更简洁的范围for的新遍历方式

string类对象三种遍历方式:

  1. for+[]
  2. 范围for(本质还是迭代器)
  3. 迭代器(begin(),end())

这个三种遍历方式不仅可以遍历string对象,还能遍历修改string中的字符

注意:在string遍历时使用最多的是for+下标方括号[]或者范围for(C++11后才支持)。begin()+end()大多数使用在需要使用STL提供的算法操作string时,比如:采用reverse逆置string。

第一种:for+下标方括号[]

int main()
{
  string str1("hello world");
  int sz = str1.size();
  for (int i = 0; i < sz; i++)
  {
    //cout<<str1.operator[](i)<<endl;
    cout << str1[i] << endl;
  }
  return 0;
}

第二种:范围for

int main()
{
  string str1("hello world");
  int sz = str1.size();
  for (auto ch : str1)//从str1读取字符给变量ch,auto会自动识别类型
  {
    cout << ch << endl;
  }
  return 0;
}

接下来单独介绍下迭代器

六、迭代器(简单介绍)

6.1 迭代器概念

迭代器(Iterator)是一种用于遍历容器(如列表、字典、集合等)元素的对象。它提供了一种统一的访问容器内部元素的方式,而不必暴露容器的具体实现细节。迭代器通常用于循环结构中,让程序员能够逐个访问容器中的元素。

int main()
{
  string str1("hello world");
  string::iterator it = str1.begin();
  while (it != str1.end())
  {
    cout << *it << endl;
    it++;
  }
  return 0;
}

虽然推荐使用上面两种方式,但是迭代器才是主流。对于链表、树等数据结构,迭代器不在乎底层实现,是通用的遍历容器。迭代器是一种像指针的东西,他可以是指针也可以不是指针,具体还是看不同编译器的底层实现,迭代器有两种类型分别:可读可修改,可读不可修改

在string中定义迭代器:

string::iterator it = str1.begin();

string::iterator it = str1.end();

简单说明

begin()返回指向第一个位置的迭代器或指针,可以用于访问第一个位置元素,而end()返回指向最后一个位置之后的迭代器,它指向的是标记字符串的结尾。

可以使用容器类型的迭代器类型来声明变量:std::vector容器,begin()和end()返回的是str::vector::iterator类型的迭代器,可以将其存储相应的变量中。

总之,存储迭代器的变量类型应该与容器的迭代器类型相匹配,以确保类型的一致性,避免编译器报错或者意外行为

6.2 反向迭代器(reverse_iterator)

反向迭代器定义:string::reverse_iterator

int main()
{
  string str1("hello world");
  string::reverse_iterator rit = str1.rbegin();
  while (rit != str1.rend())
  {
    cout << *rit << "";
    ++rit;
  }
  cout << endl;
  return 0;
}

说明:rbegin()返回逆向迭代器位置,由于本来就是倒置的,++就是向前遍历。实际上很少使用场景,正向迭代器也可以满足倒着遍历的需求。

七、Modifiers(string类对象的修改操作)

函数名称 功能说明
push_back 在字符串后尾插字符c
append 在字符串后追加一个字符串
operator+= (重点) 在字符串后追加字符串str
c_str(重点) 返回C格式字符串
find + npos(重点) 从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置
rfind 从字符串pos位置开始往前找字符c,返回该字符在字符串中的位置
substr 在str中从pos位置开始,截取n个字符,然后将其返回

对string操作时,如果能够大概预估到放多少字符,可以先通过reserve把空间预留好,减少扩容次数,提高性能

7.1 push_back

int main()
{
  string str1;//定义一个string类对象
  for (int i = 0; i < 10; i++)
  {
    str1.push_back('c');
  }
  cout << str1 << endl;
  return 0;
}

功能:将一个字符尾插到字符串中

疑问:push_back也不常用,既然支持一个字符尾插,为什么不顺便支持字符串。需要实现个支持字符串的接口,两个接口放在一起显得冗余

7.2 append

int main()
{
  string str1;
  str1.append("hello world");
  cout << str1 << endl;
  return 0;
}

功能:在字符串后追加一个字符串

对于append有很多个函数重载,这里只需要记住经常使用的就行了,其他了解下即可,但是无论是push_back,还是append,我们都不喜欢使用的,比较喜欢使用operator+=

7.3 operator+=(重要)

int main()
{
  string str1,str2;
  str1 += 'c';
  cout << str1 << endl;
  str2 += "hello world";
  cout << str2 << endl;
  str2 += str1;
  cout << str2 << endl;//输出结果:hello worldc
  return 0;
}

注意:虽然str1.push_back('c')、str1.append(1,'c')、str1+='c'三种的实现逻辑差不多,但是一般情况string类使用operator+=操作比较多,在于+=操作不仅可以连接单个字符,还可以连接字符串

7.4 assign

int main()
{
  string str1("hello world");
  str1.assign("xxx");
  cout << str1 << endl;//xxx
  return 0;
}

:将空间中数据清空再添加所需内容,就是赋值的意思。如果出现空间不足问题,会自动扩容满足当前空间需求。

7.5 insert

int main()
{
  string str1("hello world");
  str1.insert(2, "xxx");
  cout << str1 << endl;//hexxxllo world
  return 0;
}

功能:从某个位置开始插入字符

7.6 erase

int main()
{
  string str1("hello world");
  str1.erase(0, 3);
  cout << str1 << endl;
  str1.erase();
  cout << str1 << endl;
  return 0;
}

功能:从某个位置开始删除len个字符。如果需删除字符超过size,则有多少删多少

如果没有给具体需要删除几个字符,采用缺省值npos,默认全部删除。留下一行空格表示,当前空间没有释放。

7.7 replace

int main()
{
  string str1("hello world");
  str1.replace(5, 1, "%");
  cout << str1 << endl;//hello%world
  return 0;
}

功能:在字符串中某个区间位置的字符进行字符替换

小结:对于insert、erase、replace来说,底层逻辑是挪动数据,时间复杂度很高,效率很低,能不使用就不使用,建议多使用operator+=。

7.8 find

返回值:如果找到相对应的字符后,find会返回该字符所在的索引位置(从0开始的下标索引位置),如果没有匹配成功,find则会返回npos(-1);

7.8.1 size_t find(const char* s, size t pos = 0) const

size_t find(const char* s, size t pos = 0) const;
int main()
{
  string str1("file.cpp");
  size_t pos = str1.find('.');
  cout << pos << endl;
  return 0;
}

功能:find从pos开始位置,查找字符串中所需字符所在位置

7.8.2 size t find(char c,size t pos =0) const

int main()
{
  string str1("https://cplusplus.com/reference/string/string/find/");
  size_t pos = str1.find("://", 2);
  cout << pos << endl;
  return 0;
}

功能:find从pos开始位置,查找字符串中所需字符串位置,并返回开头字符的下标


【C++】C++ STL 探索:String的使用与理解(三)https://developer.aliyun.com/article/1617333

相关文章
|
10天前
|
算法 C语言 C++
【c++丨STL】list的使用
本文介绍了STL容器`list`的使用方法及其主要功能。`list`是一种双向链表结构,适用于频繁的插入和删除操作。文章详细讲解了`list`的构造函数、析构函数、赋值重载、迭代器、容量接口、元素访问接口、增删查改操作以及一些特有的操作接口如`splice`、`remove_if`、`unique`、`merge`、`sort`和`reverse`。通过示例代码,读者可以更好地理解如何使用这些接口。最后,作者总结了`list`的特点和适用场景,并预告了后续关于`list`模拟实现的文章。
25 7
|
27天前
|
存储 编译器 C语言
【c++丨STL】vector的使用
本文介绍了C++ STL中的`vector`容器,包括其基本概念、主要接口及其使用方法。`vector`是一种动态数组,能够根据需要自动调整大小,提供了丰富的操作接口,如增删查改等。文章详细解释了`vector`的构造函数、赋值运算符、容量接口、迭代器接口、元素访问接口以及一些常用的增删操作函数。最后,还展示了如何使用`vector`创建字符串数组,体现了`vector`在实际编程中的灵活性和实用性。
51 4
|
28天前
|
C语言 C++ 容器
【c++丨STL】string模拟实现(附源码)
本文详细介绍了如何模拟实现C++ STL中的`string`类,包括其构造函数、拷贝构造、赋值重载、析构函数等基本功能,以及字符串的插入、删除、查找、比较等操作。文章还展示了如何实现输入输出流操作符,使自定义的`string`类能够方便地与`cin`和`cout`配合使用。通过这些实现,读者不仅能加深对`string`类的理解,还能提升对C++编程技巧的掌握。
68 5
|
28天前
|
存储 编译器 C语言
【c++丨STL】string类的使用
本文介绍了C++中`string`类的基本概念及其主要接口。`string`类在C++标准库中扮演着重要角色,它提供了比C语言中字符串处理函数更丰富、安全和便捷的功能。文章详细讲解了`string`类的构造函数、赋值运算符、容量管理接口、元素访问及遍历方法、字符串修改操作、字符串运算接口、常量成员和非成员函数等内容。通过实例演示了如何使用这些接口进行字符串的创建、修改、查找和比较等操作,帮助读者更好地理解和掌握`string`类的应用。
50 2
|
1月前
|
存储 算法 Linux
【c++】STL简介
本文介绍了C++标准模板库(STL)的基本概念、组成部分及学习方法,强调了STL在提高编程效率和代码复用性方面的重要性。文章详细解析了STL的六大组件:容器、算法、迭代器、仿函数、配接器和空间配置器,并提出了学习STL的三个层次,旨在帮助读者深入理解和掌握STL。
52 0
|
13天前
|
存储 编译器 C语言
【c++丨STL】vector模拟实现
本文深入探讨了 `vector` 的底层实现原理,并尝试模拟实现其结构及常用接口。首先介绍了 `vector` 的底层是动态顺序表,使用三个迭代器(指针)来维护数组,分别为 `start`、`finish` 和 `end_of_storage`。接着详细讲解了如何实现 `vector` 的各种构造函数、析构函数、容量接口、迭代器接口、插入和删除操作等。最后提供了完整的模拟实现代码,帮助读者更好地理解和掌握 `vector` 的实现细节。
26 0
|
2月前
|
存储 程序员 C++
C++常用基础知识—STL库(2)
C++常用基础知识—STL库(2)
85 5
|
2月前
|
存储 安全 C++
【C++打怪之路Lv8】-- string类
【C++打怪之路Lv8】-- string类
29 1
|
2月前
|
存储 自然语言处理 程序员
C++常用基础知识—STL库(1)
C++常用基础知识—STL库(1)
77 1
|
1月前
|
存储 编译器 C++
【c++】类和对象(下)(取地址运算符重载、深究构造函数、类型转换、static修饰成员、友元、内部类、匿名对象)
本文介绍了C++中类和对象的高级特性,包括取地址运算符重载、构造函数的初始化列表、类型转换、static修饰成员、友元、内部类及匿名对象等内容。文章详细解释了每个概念的使用方法和注意事项,帮助读者深入了解C++面向对象编程的核心机制。
103 5