【C++初阶】C++STL详解(一)—— string类(下)

简介: 【C++初阶】C++STL详解(一)—— string类(下)

11.string中运算符的使用

1、operator=

 string类中对=运算符进行了重载,重载后的=运算符支持string类的赋值、字符串的赋值以及字符的赋值。

#include <iostream>
#include <string>
using namespace std;
int main()
{
  string s1;
  string s2("CSDN");
  //支持string类的赋值
  s1 = s2;
  cout << s1 << endl; //CSDN
  //支持字符串的赋值
  s1 = "hello";
  cout << s1 << endl;  //hello
  //支持字符的赋值
  s1 = 'x';
  cout << s1 << endl; //x
  return 0;
}

2、operator+=

 string类中对+=运算符进行了重载,重载后的+=运算符支持string类的复合赋值、字符串的复合赋值以及字符复合的赋值。

#include <iostream>
#include <string>
using namespace std;
int main()
{
  string s1;
  string s2("hello");
  //支持string类的复合赋值
  s1 += s2;
  cout << s1 << endl; //hello
  //支持字符串的复合赋值
  s1 += " CSDN";
  cout << s1 << endl; //hello CSDN
  //支持字符的复合赋值
  s1 += '!';
  cout << s1 << endl; //hello CSDN!
  return 0;
}

其实,operator+=的底层就是调用的push_back和append

3、operator+

string类中对+运算符进行了重载,重载后的+运算符支持以下几种类型的操作:

 string类 + string类

 string类 + 字符串

 字符串 + string类

 string类 + 字符

 字符 + string类

它们相加后均返回一个string类对象。

#include <iostream>
#include <string>
using namespace std;
int main()
{
  string s;
  string s1("super");
  string s2("man");
  char str[] = "woman";
  char ch = '!';
  //string类 + string类
  s = s1 + s2;
  cout << s << endl; //superman
  //string类 + 字符串
  s = s1 + str;
  cout << s << endl; //superwoman
  //字符串 + string类
  s = str + s1;
  cout << s << endl; //womansuper
  //string类 + 字符
  s = s1 + ch;
  cout << s << endl; //super!
  //字符 + string类
  s = ch + s1;
  cout << s << endl; //!super
  return 0;
}

4、operator>> 和 operator<<

 string类中也对>>和<<运算符进行了重载,这就是为什么我们可以直接使用>>和<<对string类进行输入和输出的原因。


istream& operator>> (istream& is, string& str);

ostream& operator<< (ostream& os, const string& str);

#include <iostream>
#include <string>
using namespace std;
int main()
{
  string s;
  cin >> s; //输入
  cout << s << endl; //输出
  return 0;
}

5、!=、<、<=、>等

 string类中还对一系列关系运算符进行了重载,它们分别是==、!=、<、<=、>、>=。重载后的关系运算符支持string类和string类之间的关系比较、string类和字符串之间的关系比较、字符串和string类之间的关系比较。

#include <iostream>
#include <string>
using namespace std;
int main()
{
  string s1("abcd");
  string s2("abde");
  cout << (s1 > s2) << endl; //0
  cout << (s1 < s2) << endl; //1
  cout << (s1 == s2) << endl; //0
  return 0;
}

注意:这些重载的关系比较运算符所比较的都是对应字符的ASCII码值

12.string中与迭代器相关的函数


1、与正向迭代器相关的函数

begin函数:返回一个指向字符串第一个字符的迭代器。

函数原型:

iterator begin();

 const_iterator begin() const;

end函数:返回一个指向字符串结束字符的迭代器,即’\0’。

函数原型:

iterator end();

 const_iterator end() const;

使用示例:

#include <iostream>
#include <string>
using namespace std;
int main()
{
  string s("hello");
  //正向迭代器
  string::iterator it = s.begin();
  while (it != s.end())
  {
    cout << *it;
    it++;
  }
  cout << endl; //hello
  return 0;
}

image.png2、与反向迭代器相关的函数

rbegin函数:返回指向字符串最后一个字符的反向迭代器。

函数原型:

reverse_iterator rbegin();

 const_reverse_iterator rbegin() const;

rend函数:返回指向字符串第一个字符前面的理论元素的反向迭代器。

函数原型:

reverse_iterator rend();

 const_reverse_iterator rend() const;

使用示例:

#include <iostream>
#include <string>
using namespace std;
int main()
{
  string s("hello");
  //反向迭代器
  string::reverse_iterator rit = s.rbegin();
  while (rit != s.rend())
  {
    cout << *rit;
    rit++;
  }
  cout << endl; //olleh
  return 0;
}

f6fc2f619e7c4189b248a6979585dade.png

13.string与字符串之间的转换

1、将字符串转换为string

 将字符串转换为string很简单,在前面讲string的定义方式时就有说到。

#include <iostream>
#include <string>
using namespace std;
int main()
{
  //方式一
  string s1("hello world");
  //方式二
  char str[] = "hello world";
  string s2(str);
  cout << s1 << endl; //hello world
  cout << s2 << endl; //hello world
  return 0;
}

2、使用c_str或data将string转换为字符串

const char* c_str() const;

const char* data() const;

区别:

在C++98中,c_str()返回 const char* 类型,返回的字符串会以空字符结尾。

在C++98中,data()返回 const char* 类型,返回的字符串不以空字符结尾。

但是在C++11版本中,c_str()与data()用法相同。

#include <iostream>
#include <string>
using namespace std;
int main()
{
  string s("hello world ");
  const char* str1 = s.data();
  const char* str2 = s.c_str();
  cout << str1 << endl;
  cout << str2 << endl;
  return 0;
}

兼容C语言,相互配合:f87071df951e485995b7ae74970169a5.pngC语言与C++中字符串读取结束的区别:image.png

14.string中子字符串的提取

1、使用substr函数提取string中的子字符串

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

#include <iostream>
#include <string>
using namespace std;
int main()
{
  string ur1 = "https://cplusplus.com/reference/string/string/";
  size_t pos1 = ur1.find("://");
  string protocol;//协议
  if (pos1 != string::npos)//找到了
  {
    protocol = ur1.substr(0, pos1);//substr(pos, n)提取pos位置开始的n个字符序列作为返回值
  }
  cout << protocol << endl;
  string domain;//域名
  string uri;//资源名
  size_t pos2 = ur1.find("/", pos1 + 3);
  if (pos1 != string::npos)//找到了
  {
    domain = ur1.substr(pos1 + 3, pos2 - (pos1 + 3));
    uri = ur1.substr(pos2 + 1);
  }
  cout << domain << endl;
  cout << uri << endl;
  return 0;
}

f5c9829688a5445baedbeac53cd7a350.png2、使用copy函数将string的子字符串复制到字符数组中

size_t copy (char* s, size_t len, size_t pos = 0) const;

#include <iostream>
#include <string>
using namespace std;
int main()
{
  string s("abcdef");
  char str[20];
  //copy(str, n, pos)复制pos位置开始的n个字符到str字符串
  size_t length = s.copy(str, 4, 2);
  //copy函数不会在复制内容的末尾附加'\0',需要手动加
  str[length] = '\0';
  cout << str << endl; //dcef
  return 0;
}

15.string中的getline函数

在使用>>进行输入操作时,当>>读取到空格便会停止读取,基于此,我们将不能用>>将一串含有空格的字符串读入到string对象中。

#include <iostream>
#include <string>
using namespace std;
int main()
{
  string s;
  cin >> s; //输入:hello CSDN
  cout << s << endl; //输出:hello
  return 0;
}

这时,我们就需要用getline函数完成一串含有空格的字符串的读取操作了。

用法一:

istream& getline (istream& is, string& str);

getline函数将从is中提取到的字符存储到str中,直到读取到换行符’\n’为止。

#include <iostream>
#include <string>
using namespace std;
int main()
{
  string s;
  getline(cin, s); //输入:hello CSDN
  cout << s << endl; //输出:hello CSDN
  return 0;
}

用法二:

istream& getline (istream& is, string& str, char delim);

getline函数将从is中提取到的字符存储到str中,直到读取到分隔符delim或换行符’\n’为止。

#include <iostream>
#include <string>
using namespace std;
int main()
{
  string s;
  getline(cin, s, 'D'); //输入:hello CSDN
  cout << s << endl; //输出:hello CS
  return 0;
}

16.总结:

今天我们认识并具体学习了STL中string类,开启了STL学习的大门。接下来,我们将进行STL中string类的模拟实现。希望我的文章和讲解能对大家的学习提供一些帮助。

当然,本文仍有许多不足之处,欢迎各位小伙伴们随时私信交流、批评指正!我们下期见~

c3ad96b16d2e46119dd2b9357f295e3f.jpg

相关文章
|
4月前
|
缓存 算法 程序员
C++STL底层原理:探秘标准模板库的内部机制
🌟蒋星熠Jaxonic带你深入STL底层:从容器内存管理到红黑树、哈希表,剖析迭代器、算法与分配器核心机制,揭秘C++标准库的高效设计哲学与性能优化实践。
C++STL底层原理:探秘标准模板库的内部机制
|
4月前
|
编解码 Java 开发者
Java String类的关键方法总结
以上总结了Java `String` 类最常见和重要功能性方法。每种操作都对应着日常编程任务,并且理解每种操作如何影响及处理 `Strings` 对于任何使用 Java 的开发者来说都至关重要。
355 5
|
11月前
|
编译器 C++ 容器
【c++丨STL】基于红黑树模拟实现set和map(附源码)
本文基于红黑树的实现,模拟了STL中的`set`和`map`容器。通过封装同一棵红黑树并进行适配修改,实现了两种容器的功能。主要步骤包括:1) 修改红黑树节点结构以支持不同数据类型;2) 使用仿函数适配键值比较逻辑;3) 实现双向迭代器支持遍历操作;4) 封装`insert`、`find`等接口,并为`map`实现`operator[]`。最终,通过测试代码验证了功能的正确性。此实现减少了代码冗余,展示了模板与仿函数的强大灵活性。
315 2
|
11月前
|
存储 算法 C++
【c++丨STL】map/multimap的使用
本文详细介绍了STL关联式容器中的`map`和`multimap`的使用方法。`map`基于红黑树实现,内部元素按键自动升序排列,存储键值对,支持通过键访问或修改值;而`multimap`允许存在重复键。文章从构造函数、迭代器、容量接口、元素访问接口、增删操作到其他操作接口全面解析了`map`的功能,并通过实例演示了如何用`map`统计字符串数组中各元素的出现次数。最后对比了`map`与`set`的区别,强调了`map`在处理键值关系时的优势。
609 73
|
8月前
|
对象存储 C++ 容器
c++的string一键介绍
这篇文章旨在帮助读者回忆如何使用string,并提醒注意事项。它不是一篇详细的功能介绍,而是一篇润色文章。先展示重载函数,如果该函数一笔不可带过,就先展示英文原档(附带翻译),最后展示代码实现与举例可以直接去看英文文档,也可以看本篇文章,但是更建议去看英文原档。那么废话少说直接开始进行挨个介绍。
162 3
|
10月前
|
编译器 C++ 容器
【c++11】c++11新特性(上)(列表初始化、右值引用和移动语义、类的新默认成员函数、lambda表达式)
C++11为C++带来了革命性变化,引入了列表初始化、右值引用、移动语义、类的新默认成员函数和lambda表达式等特性。列表初始化统一了对象初始化方式,initializer_list简化了容器多元素初始化;右值引用和移动语义优化了资源管理,减少拷贝开销;类新增移动构造和移动赋值函数提升性能;lambda表达式提供匿名函数对象,增强代码简洁性和灵活性。这些特性共同推动了现代C++编程的发展,提升了开发效率与程序性能。
414 12
|
8月前
|
人工智能 机器人 编译器
c++模板初阶----函数模板与类模板
class 类模板名private://类内成员声明class Apublic:A(T val):a(val){}private:T a;return 0;运行结果:注意:类模板中的成员函数若是放在类外定义时,需要加模板参数列表。return 0;
220 0
|
8月前
|
存储 编译器 C语言
关于string的‘\0‘与string,vector构造特点,反迭代器与迭代器类等的讨论
你真的了解string的'\0'么?你知道创建一个string a("abcddddddddddddddddddddddddd", 16);这样的string对象要创建多少个对象么?你知道string与vector进行扩容时进行了怎么的操作么?你知道怎么求Vector 最大 最小值 索引 位置么?
210 0
|
8月前
|
存储 编译器 程序员
c++的类(附含explicit关键字,友元,内部类)
本文介绍了C++中类的核心概念与用法,涵盖封装、继承、多态三大特性。重点讲解了类的定义(`class`与`struct`)、访问限定符(`private`、`public`、`protected`)、类的作用域及成员函数的声明与定义分离。同时深入探讨了类的大小计算、`this`指针、默认成员函数(构造函数、析构函数、拷贝构造、赋值重载)以及运算符重载等内容。 文章还详细分析了`explicit`关键字的作用、静态成员(变量与函数)、友元(友元函数与友元类)的概念及其使用场景,并简要介绍了内部类的特性。
354 0
|
11月前
|
编译器 C++
类和对象(中 )C++
本文详细讲解了C++中的默认成员函数,包括构造函数、析构函数、拷贝构造函数、赋值运算符重载和取地址运算符重载等内容。重点分析了各函数的特点、使用场景及相互关系,如构造函数的主要任务是初始化对象,而非创建空间;析构函数用于清理资源;拷贝构造与赋值运算符的区别在于前者用于创建新对象,后者用于已存在的对象赋值。同时,文章还探讨了运算符重载的规则及其应用场景,并通过实例加深理解。最后强调,若类中存在资源管理,需显式定义拷贝构造和赋值运算符以避免浅拷贝问题。