《string类的使用介绍》

news2024/11/16 8:48:49

本文主要介绍string的常见的接口的使用

文章目录

  • 一、什么是string类
  • 二、string类的使用
    • 1、string类对象的常见构造
    • 2、string类对象的容量操作
    • 3、string类对象的访问及遍历操作
      • ①operator[ ]的用法
      • ②迭代器
      • ③范围for
    • 4、string类对象的修改操作
      • ①push_back
      • ②append
      • ③operator+=(这是最常用的一个函数)
      • ④c_str
      • ⑤find函数
      • ⑥rfind
      • ⑦substr
      • ⑧利用find取出网站的域名以及删除前缀
      • ⑨利用replace和find替换字符
      • ⑩swap
    • 5、string类非成员函数
      • getline
    • 6、其他函数
      • ① stoi——字符串转为整型
      • ② to_string——其他类型转为字符串



一、什么是string类

  1. 字符串是表示字符序列的类
  2. 标准的字符串类提供了对此类对象的支持,其接口类似于标准字符容器的接口,但添加了专门用于操作单字节字符字符串的设计特性。
  3. string类是使用char(即作为它的字符类型,使用它的默认char_traits和分配器类型(关于模板的更多信息,请参阅basic_string)。
  4. string类是basic_string模板类的一个实例,它使用char来实例化basic_string模板类,并用char_traits和allocator作为basic_string的默认参数(根于更多的模板信息请参考basic_string)。
  5. 注意,这个类独立于所使用的编码来处理字节:如果用来处理多字节或变长字符(如UTF-8)的序列,这个类的所有成员(如长度或大小)以及它的迭代器,将仍然按照字节(而不是实际编码的字符)来操作

总结:

  1. string是表示字符串的字符串类

  2. 该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。

  3. string在底层实际是**:basic_string模板类的别名**,typedef basic_string<char, char_traits, allocator> string;

  4. 不能操作多字节或者变长字符的序列。

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

二、string类的使用

1、string类对象的常见构造

函数名称功能
string s;构造空的string类对象,即空字符串
string s1(const char* s);复制s指向的字符串
string s2(size_t n,char c);生成n个c字符的字符串
string s3(const string&s);用string类对象拷贝构造

具体使用:

    string s;         // 构造空的string类对象s
 
	string s2("hello");//复制hello字符串给s2对象
 
	string s3(10, 'x');//生成10个x的字符串
 
	string s4(s2);     //用s2拷贝构造对象s4

2、string类对象的容量操作

函数功能
size返回字符串有效个数
length返回有效字符串个数
capacity返回总空间的大小
empty判断字符串是否为空
clear清空字符串
reserve为字符串预留空间(有点像malloc)
resize将有效的字符个数改成n个,多出的空间用字符c填充(有点像calloc)

具体使用

void test2()
{
	string s("hello");
 
	cout <<"size:"<< s.size() << endl;
	cout <<"length:"<< s.length() << endl;
	cout <<"capacity:"<< s.capacity() << endl;
	cout <<"empty:"<< s.empty() << endl;
}

结果如下:
在这里插入图片描述
对于clear函数,只是将s中的字符串清空,size置为0,但是不改变底层空间capacity的大小

void test2()
{
	string s("hello");
 
	cout <<"size:"<< s.size() << endl;
	cout <<"length:"<< s.length() << endl;
	cout <<"capacity:"<< s.capacity() << endl;
	cout <<"empty:"<< s.empty() << endl;
	cout << "----------" << endl;
	s.clear();
	cout << "size:" << s.size() << endl;
	cout << "capacity:" << s.capacity() << endl;
	cout << "empty:" << s.empty() << endl;
 
}

在这里插入图片描述
我们再来详细看看resize:

void resize (size_t n);
void resize (size_t n, char c);

①按照给定的字符扩容

void test3()
{
	string s("hello");
	s.resize(10, 'x');//将s中的有效字符个数增加到10个,后面多出的位置用x填充
	cout << "size:" << s.size() << endl;
	cout << "capacity:" << s.capacity() << endl;
	cout << s << endl;
}

结果如下:
在这里插入图片描述
②默认给定的“\0”来填充扩容

void test4()
{
	string s("hello");
	s.resize(15);//将s中的有效字符个数增加到15个,后面多出的位置用"\0"填充
	cout << "size:" << s.size() << endl;
	cout << "capacity:" << s.capacity() << endl;
	cout << s << endl;
}

结果如下:
在这里插入图片描述
③当是缩小大小时,会截断字符

void test5()
{
	string s("hello");
	s.resize(3);//将s中的有效字符个数减少到3个,只剩下原来的前三个
	cout << "size:" << s.size() << endl;
	cout << "capacity:" << s.capacity() << endl;
	cout << s << endl;
}

结果如下:
在这里插入图片描述
我们再来详细看看reserve:

void reserve (size_t n = 0);

①当n大于当前对象的容量时,将容量扩大到n或者大于n

void test6()
{
	string s;
	cout << "size:" << s.size() << endl;
	cout << "capacity:" << s.capacity() << endl;
	cout << "----------------" << endl;
	s.reserve(100);//将原来的capacity扩大到100
	cout << "size:" << s.size() << endl;
	cout << "capacity:" << s.capacity() << endl;
}

结果如下:
在这里插入图片描述
当n小于容量时,不会缩小到容量

void test6()
{
	string s;
	cout << "size:" << s.size() << endl;
	cout << "capacity:" << s.capacity() << endl;
	cout << "----------------" << endl;
	s.reserve(100);//将原来的capacity扩大到100
	cout << "size:" << s.size() << endl;
	cout << "capacity:" << s.capacity() << endl;
	cout << "----------------" << endl;
	s.reserve(20);//不会将之前的capacity缩小
	cout << "size:" << s.size() << endl;
	cout << "capacity:" << s.capacity() << endl;
}

结果如下:
在这里插入图片描述
我们可以看到容量并没有缩小!!!

总结:

① resize(size_t n) 与 resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不同的是当字符个数增多时:resize(n)用0来填充多出的元素空间,resize(size_t n, char c)用字符c来填充多出的元素空间。注意:resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间总大小不变。
② reserve(size_t res_arg=0):为string预留空间,不改变有效元素个数,当reserve的参数小于string的底层空间总大小时,reserve不会改变容量大小

3、string类对象的访问及遍历操作

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

operator [] (i)

char& operator[] (size_t pos);
const char& operator[] (size_t pos) const;

我们知道string类字符串的底层其实是数组实现的,于是我们可以采用下标的方式进行遍历
在这里插入图片描述
举例说明:

void test7()
{
	string s1("hello");
	const string s2("HELLO");
	cout << s1 << " " << s2 << endl;
	cout << s1[0] << " " << s2[0] << endl;
 
	s1[0] = 'x';
	cout << s1 << endl;
 
	//s2[0] = 'x';const类对象不能修改
}

在这里插入图片描述


at

char& at (size_t pos);
const char& at (size_t pos) const;

at的使用:

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

int main()
{
    std::string str("test string");
    for (size_t i = 0; i < str.size(); ++i)
    {
        cout << str.at(i) << " ";
    }
    return 0;
}

结果展示:
在这里插入图片描述

总结:
operator[ ]和at函数功能相同,都是返回pos位置的字符,但是不同的是,at失败会assert断言错误,operator[ ]会抛异常


三种遍历操作:(常用)

①operator[ ]的用法

void test8()
{	
	string s1("hello");
	string s2(s1);//拷贝构造
	for (size_t i = 0; i < s2.size(); ++i)
	{
		cout << s2.operator[](i) << " ";
		cout << s2[i] << " ";
	}
	cout << endl;
	for (size_t i = 0; i < s2.size(); ++i)
	{
		s2[i] += 1;//支持修改
	}
	cout << s2 << endl;
}

②迭代器

注意:这里暂时将迭代器想象成像指针一样的类型

void test9()
{
	string s("hello");
	//迭代器的用法
	//string::iterator it = s.begin();
	auto it = s.begin();// C++11之后,直接使用auto定义迭代器,让编译器推到迭代器的类型
	while (it !=s.end())
	{
		cout << *it << endl;
		++it;
	}
}

③范围for

其实范围for的底层是将它给处理成了迭代器

void test10()
{
	string s("hello");
	for (auto ch : s)
		cout << ch << endl;
	//把s中的每个字符取出来,赋值给ch,不需要++,判断结束,自动往后迭代
}

4、string类对象的修改操作

函数功能
push_back在字符串后面尾插字符c
append在字符串后面追加字符串
operator+=在字符串后面追加字符串
c_str返回C格式字符串(C形式的字符串打印时,遇到\0就停止了)
find+npos从字符串pos位置开始,往后找字符c,返回该字符在字符串中的位置
rfind从字符串pos位置开始,往前找字符c,返回该字符在字符串中的位置
substr在字符串中,从pos位置开始,截取n个字符,然后将其返回
replace将指定位置替换为自己想要的
swap交换两个两个字符串(直接交换指针,效率更高)

注意:

  1. 在string尾部追加字符时,s.push_back© / s.append(1, c) / s += 'c’三种的实现方式差不多,一般
    情况下string类的+=操作用的比较多,+=操作不仅可以连接单个字符,还可以连接字符串。
  2. 对string操作时,如果能够大概预估到放多少字符,可以先通过reserve把空间预留好。

①push_back

void push_back (char c);
void test11()
{
	string s("xxx");
	cout << s << endl;
	s.push_back('H');
	s.push_back('E');
	s.push_back('L');
	s.push_back('L');
	s.push_back('O');
	cout << s << endl;//将HELLO依次拼接到xxx后面
}

结果如下:
在这里插入图片描述

②append

string& append (const string& str);
string& append (const char* s);
void test12()
{
	string s1("hello");
	string s2("C++");
	s1.append(s2);//直接拼接一个对象字符串
 
	cout << s1 << endl;
	s1.append("haha");//直接拼接一个字符串
	cout << s1 << endl;
}

结果展示:
在这里插入图片描述

③operator+=(这是最常用的一个函数)

string& operator+= (const string& str);
string& operator+= (const char* s);
string& operator+= (char c);
void test13()
{
	string s1("hello");
	string s2("world");
	s1 += s2;
	cout << s1 << endl;
 
	s1 += "xxx";
	cout << s1 << endl;
 
	s1 += 'A';
	cout << s1 << endl;
}

结果如下:
在这里插入图片描述

④c_str

const char* c_str() const;
void test14()
{
	string s("hello");
	//以语言的格式打印字符串
	cout << s.c_str() << endl;
}

结果如下:
在这里插入图片描述

⑤find函数

注意:static const size_t npos = -1;//其实npos就是size_t的最大值

size_t find (const string& str, size_t pos = 0) const;
	
size_t find (const char* s, size_t pos = 0) const;
	
size_t find (const char* s, size_t pos, size_t n) const;
	
size_t find (char c, size_t pos = 0) const;
void test15()
{
	string s1("http://www.cplusplus.com/reference/string/string/find/");
	
	size_t pos1 = s1.find("com");//正向查找com字符串
	cout << pos1 << endl;
 
	string s2("http");
	size_t pos2 = s1.find(s2);//正向查找与s2对象匹配的字符串
	cout << pos2<< endl;
 
	size_t pos3 = s1.find('p');//正向查找字符p
	cout << pos3 << endl;
}

结果展示:
在这里插入图片描述

⑥rfind

size_t rfind (const string& str, size_t pos = npos) const;
	
size_t rfind (const char* s, size_t pos = npos) const;
 
size_t rfind (const char* s, size_t pos, size_t n) const;
	
size_t rfind (char c, size_t pos = npos) const;
void test16()
{
	string s1("http://www.cplusplus.com/reference/string/string/find/");
 
	size_t pos1 = s1.rfind("string");//反向查找是s1中第一次出现的string的首位置
	cout << pos1 << endl;
 
	string s2("cplusplus");
	size_t pos2 = s1.rfind(s2);//反向查找s1中与s2对象匹配的首位置
	cout << pos2 << endl;
 
	size_t pos3 = s1.rfind('h'); //反向查找s1中h字符
	cout << pos3 << endl;
}

结果展示:

在这里插入图片描述

⑦substr

string substr (size_t pos = 0, size_t len = npos) const;
void test17()
{
	//获取file的后缀
	string file("string.cpp");
	size_t pos = file.rfind('.');//反向查找 . 点
	string suffix(file.substr(pos,file.size()-pos));//从点开始,包括点的后面部分
	cout << suffix << endl;
}

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

string& replace (size_t pos,  size_t len,  const string& str);
string& replace (size_t pos,  size_t len,  const string& str);
string& replace (size_t pos,  size_t len,  size_t n, char c);

⑧利用find取出网站的域名以及删除前缀

void test()
{
	// 取出url中的域名
	string url("http://www.cplusplus.com/reference/string/string/find/");
	cout << url << endl;
	size_t start = url.find("://");
	if (start == string::npos)
	{
		cout << "invalid url" << endl;
		return;
	}
	start += 3;
	size_t finish = url.find('/', start);
	string address = url.substr(start, finish - start);
	cout << address << endl;

	// 删除url的协议前缀
	size_t pos = url.find("://");
	url.erase(0, pos + 3);
	cout << url << endl;
}

结果如下:
在这里插入图片描述

⑨利用replace和find替换字符

面试题:将这个字符串的空格替换为%%20.
`“hello world I love ereryday!”

方法1:找到空格后替换

int main()
{
	string s1 = "hello world I love you!";
	//我们提前算好我们的空格,然后提前开空间
	size_t num = 0;
	for (auto ch : s1)
	{
		if (ch == ' ')
		{
			++num;
		}
	}
	//提前开空间,避免replace时扩容
	s1.reserve(s1.size() + 3 * num);
	//第二个参数是缺省值=0,就是从开始的地方找
	size_t pos = s1.find(' ');
	while (string::npos != pos)
	{
		s1.replace(pos, 1, "%%20");
		//在pos之后第四个位置开始找
		pos = s1.find(' ',pos+4);
	}
	cout << s1 << endl;
}

方法2:空间换时间,创建新的string对象,遍历原字符串,不是空格就尾插字符,是空格就尾插%%20

//第二种方法以空间换时间
int main()
{
	string s1 = "hello world I love you!";
	//我们提前算好我们的空格,然后提前开空间
	string tmp;
	for (auto ch : s1)
	{
		if (ch != ' ')
		{
			tmp += ch;
		}
		if (ch == ' ')
		{
			tmp += "%% 20";
		}
	}
	s1 = tmp;
	cout << s1 << endl;
}

⑩swap

在我们的string中我们也有一个交换函数。库里面也有一个swap。
我们使用string中swap效率更高。

因为在我们的string中可以直接交换指针,指向不同的字符串。
而库中的swap,我们还要用一个临时变量去交换。

在这里插入图片描述
在这里插入图片描述

int main()
{
	string s1("abcd");
	string s2("xxxx");
	
	//用string中的交换
	s1.swap(s2);
	cout << s1 << endl << s2 << endl;

	//用库中的交换
	swap(s1, s2);
	cout << s1 << endl << s2 << endl;
}

5、string类非成员函数

函数功能
operator+尽量少用,因为是传值返回,导致拷贝效率低
operator>>流插入运算符重载
operator<<流提取运算符重载
getline获取一行字符串
relational operators大小比较

getline

输入输出问题:

void test18()
{
	string s;
	cin >> s;//输入hello world
	cout << s << endl;//只会打印hello
}

我们知道cin标准输入,当从键盘上面读取到空格或者\n时,会停止读取,这时候就要用到getline函数了

istream& getline (istream& is, string& str, char delim);
//从is中读取字符串,储存在str对象中,直到遇到delim界限符或者\n停止(自己指定)
 
istream& getline (istream& is, string& str);
//从is中读取字符串,储存在str对象中,直到遇到\n停止

演示遇到指定字符就停止读取

void test18()
{
	string s1;
	getline(cin,s1,'e');//输入hello world,
	cout << s1 << endl;//输出h
}

演示遇到\n停止

void test18
{
	string s2;
	getline(cin, s2);//输入hello world
	cout << s2 << endl;//输出hello world
}

总结:
以后使用getline

string s1; 
getline(cin,s1);

大小比较问题:
我们的string的大小比较就和stercmp一样,是比较字符的ASCII的大小

void test19()
{
	string s1("hello");
	string s2("string");
	cout << (s1 > s2) << endl;//输出0
}

这里的有点不一样,比较的是第一个字符的ASCII码值的大小,若第一个相等则比较第二个,返回一个bool值,以此类推。

6、其他函数

做OJ题的时候比较常用

① stoi——字符串转为整型

void test20()
{
	int val = stoi("12345");
	cout << val << endl;
}

② to_string——其他类型转为字符串

void test21()
{
	string str = to_string(3.14);
	cout << str << endl;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/498059.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

刷题笔记8| 344.反转字符串, 541. 反转字符串II, 剑指Offer 05.替换空格

344.反转字符串 编写一个函数&#xff0c;其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。 不要给另外的数组分配额外的空间&#xff0c;你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。 输入&#xff1a;s ["h","e",…

索引—MySQL

文章目录 1.定义以及相关知识1.1定义1.2数据库保存数据的基本单位 2.MySQL中索引分类2.1B树和B树2.2主键索引&#xff08;聚簇索引&#xff09;2.3非聚簇索引2.4覆盖索引2.5复合索引&#xff08;联合索引&#xff09;2.6基于B树的索引2.7hash索引 1.定义以及相关知识 1.1定义 …

okio篇--总览

看源码第一步&#xff0c;先去看看官网对okio的介绍&#xff1a; Okio 首先第一段&#xff1a; okio对bytes&#xff0c;做了两种形式的封装&#xff1a;ByteString和Buffer。 其中ByteString&#xff0c;是针对字符类的数据&#xff0c;内部封装一个byte数组&#xff0c;封…

网络协议与攻击模拟-06-ICMP重定向

■0网络不可达 ■2协议不可达 类型4源抑制 类型5重定向 2、 ICMP 常见的报文 响应请求 使用 ping 请求&#xff08; type 0)响应&#xff08; type 8) 目标不可达 type 3 源抑制 源抑制则充当一个控制流量的角色&#xff0c;它通知主机减少数据报流量&#xff0c;由于 I…

Django初识

1、简介 Django&#xff0c;是用python语言写的开源web开发框架&#xff0c;并遵循MVC设计。劳伦斯出版集团为了开发以新闻内容为主的网站&#xff0c;而开发出来了这个框架&#xff0c;于2005年7月在BSD许可证下发布。这个名称来源于比利时的爵士音乐家DjangoReinhardt&#…

操作系统第二章——进程与线程(中)

和光同尘&#xff0c;与时舒卷 文章目录 2.2.1 调度的概念&#xff0c;层次知识总览调度的基本概念高级调度低级调度中级调度三层调度的联系&#xff0c;对比进程的挂起态和七状态模型知识回顾 2.2.2 进程调度的时机&#xff0c;切换与过程&#xff0c;方式知识总览进程调度的时…

【C++】第二站:类和对象(中)拷贝构造函数

文章目录 一、拷贝构造函数的概念二、拷贝构造函数的特性三、深度剖析拷贝构造函数不采用引用会无限递归的原因1.C对于传参的两个规定2.如何解开这个无穷递归 四、拷贝构造函数的其他特性五、拷贝构造的一些使用场景 一、拷贝构造函数的概念 拷贝构造函数&#xff1a;只有单个形…

2.2 Linux控制台访问CLI

系列文章目录 第1章 Linux Shell简介 第2章 Shell基础 <本章所在位置> 第3章 Bash Shell基础命令 第4章 Bash Shell命令进阶 第5章 Linux Shell深度理解 第6章 Linux环境变量 第7章 Linux文件权限 第8章 Linux文件系统的管理 第9章 Linux软件安装 第10章 Linux文本编辑器…

【MySQL】搭建出高可用性、高性能的MySQL集群要考虑的事是蛮多的,你看看会不会?

MySQL 架构设计数据同步负载均衡安全性监控和维护注意的点1. 确定节点数量和配置2. 选择合适的硬件和网络设备3. 避免单点故障4. 定期备份和恢复测试5. 定期更新和升级 Java工程师使用集群步骤最后 MySQL集群是一种高可用性、高性能的数据库解决方案&#xff0c;它可以通过多个…

基于Django实现的TMS物流管理系统(附源码下载)

基于Django实现的物流管理系统&#xff08;TMS&#xff0c;Transportation Management System&#xff09; 特点 前端基于Bootstrap 4框架和AdminLTE框架。使用MySQL作为数据库后端。实现了运单录入、发车出库、到货签收、客户签收等基本功能。拥有较为完善的报表功能和财务管…

Java—JDK8新特性—Lambda表达式【内含思维导图】

目录 JDK8新特性 2.Lambda表达式 思维导图 2.1 什么是Lambda表达式 2.2 为什么使用Lamdba表达式 2.3 Lambda表达式基本语法 2.4 类型推断 2.5 Lambda练习 2.6 Lambda常用场景 JDK8新特性 官网提供网址&#xff1a;JDK 8 Features 2.Lambda表达式 思维导图 2.1 什么是…

浅谈Dom和Bom(清晰易懂版)

DOM&#xff08;文档对象模型&#xff09; DOM 是浏览器提供的一种操作网页内容和结构的 API&#xff0c;它将 Web 页面表示为一个树形结构&#xff0c;其中每一个 HTML 元素都是一个节点&#xff0c;可以通过 DOM API 对其进行访问和操作。DOM API 包括了一系列方法和属性&am…

Shapes布局-文字环绕动画

文章目录 说明实现以及语法动画渐变裁切图形变换的动画效果 说明 Shapes也有形状、图形的意思&#xff0c;我们可以在页面中创建图形&#xff0c;并让内容环绕在定义的图形边上。 Shapes的官方文档&#xff1a;https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Shapes/F…

YOLOv8 来了,快速上手实操

目录 YOLOv8的优点安装ultralytics使用YOLOv8n在图像上进行PredictTasks与 ModesModes - 模式分类Tasks - 任务分类 &#x1f468;‍&#x1f4bb; 作者简介&#xff1a;程序员半夏 , 一名全栈程序员&#xff0c;擅长使用各种编程语言和框架&#xff0c;如JavaScript、React、N…

SpringBoot集成Redis—缓存穿透解决方案与哨兵模式实战

目录 1、环境准备 1&#xff09;pom.xml引入Redis依赖 2) 演示业务场景 2、SpringBoot集成Redis单机模式 1&#xff09; 通过MyBatis逆向工程生成实体Bean和数据持久层 2) application.yml 中配置redis连接信息 3) 启动redis服务 4) XinTuProductRedisController类 5…

一图看懂 yarl 模块:为URL解析和更改提供了方便的URL类, 资料整理+笔记(大全)

本文由 大侠(AhcaoZhu)原创&#xff0c;转载请声明。 链接: https://blog.csdn.net/Ahcao2008 一图看懂 yarl 模块&#xff1a;为URL解析和更改提供了方便的URL类, 资料整理笔记&#xff08;大全&#xff09; 摘要模块图类关系图模块全展开【yarl】统计常量模块1 yarl._quoting…

Python图形界面开发——系统资源监视器System-Monitor

Python图形界面程序怎么开发呢&#xff1f;很多人推荐python自带的tkinter自带库&#xff0c;还有pyqt这个这种拖拽式界面开发方案&#xff0c;但是他们开发界面比较难定制界面样式。现在web前端这么多框架用来开发python的图形界面其实不是很好&#xff1f;下面这么案例就是用…

Python爬虫 | 一文解决文章付费限制问题

本文概要 本篇文章主要介绍利用Python爬虫爬取付费文章&#xff0c;适合练习爬虫基础同学&#xff0c;文中描述和代码示例很详细&#xff0c;干货满满&#xff0c;感兴趣的小伙伴快来一起学习吧&#xff01; &#x1f31f;&#x1f31f;&#x1f31f;个人简介&#x1f31f;&…

项目内训(2023.5.6)

目录 Nacos是什么&#xff1f; 领域模型是什么&#xff1f; domain模块一般是干什么的&#xff1f; 在小乌龟中合并其他分支的作用是什么&#xff1f; nacos的配置文件 服务集群、服务提供、服务更加灵活庞大、消费服务、访问比较麻烦&#xff0c;A和B服务一起访问 系统结…

Qt5.9学习笔记-事件(四)Qt5.9中常见事件

⭐️我叫忆_恒心&#xff0c;一名喜欢书写博客的在读研究生&#x1f468;‍&#x1f393;。 如果觉得本文能帮到您&#xff0c;麻烦点个赞&#x1f44d;呗&#xff01; 近期会不断在专栏里进行更新讲解博客~~~ 有什么问题的小伙伴 欢迎留言提问欧&#xff0c;喜欢的小伙伴给个三…