【C++】C++标准模板库STL (一) string类的使用详解
前言
在前一章种我们介绍了C++中的模板的使用,这是一种泛型编程,模板的使用能让我们减少大量的相似代码,减少我们的代码量与工作量,写出更加高效简洁的代码,模板如此好用,但还是要我们先出写一个泛型类或函数,才能使用。有没有办法直接不写泛型类或函数就能使用一些常见的数据结构与算法的代码呢?答案是有的!C++给我们提供了标准模板库STL,这是一个相当重要的库,它就完美解决了上面的问题,相信学完以后你会对它爱不释手!
C++标准模板库STL (一)
- 一、STL的基础介绍
- 1. 什么是STL
- 2. STL的版本
- 3. STL的六大组件
- 二、string类的介绍
- 1. 为什么学习string类
- 2. 标准库中的string类
- 三、string类的常用接口说明
- 1. string类对象的常见构造函数
- 2. string类对象的容量操作
- 3. string类对象的单个元素访问
- 4. string类对象的元素的遍历
- 5.string类对象的修改操作
- 6.string类对象的一些其他操作
- 7.getline函数
- 四、结语
一、STL的基础介绍
1. 什么是STL
STL(standard template libaray-标准模板库):是C++标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架。
2. STL的版本
- 原始版本
Alexander Stepanov、Meng Lee 在惠普实验室完成的原始版本,本着开源精神,他们声明允许任何人任意运用、拷贝、修改、传播、商业使用这些代码,无需付费。唯一的条件就是也需要向原始版本一样做开源使用。 HP 版本–所有STL实现版本的始祖。 - P. J. 版本
由P. J. Plauger开发,继承自HP版本,被Windows Visual C++采用,不能公开或修改,缺陷:可读性比较低,符号命名比较怪异。 - RW版本
由Rouge Wage公司开发,继承自HP版本,被C+ + Builder 采用,不能公开或修改,可读性一般。 - SGI版本
由Silicon Graphics Computer Systems,Inc公司开发,继承自HP版 本。被GCC(Linux)采用,可移植性好,可公开、修改甚至贩卖,从命名风格和编程风格上看,阅读性非常高。如果你要深入学习STL想要阅读部分源代码,可以主要参考这个版本。
3. STL的六大组件

二、string类的介绍
string类是STL中的容器,也是我们学习STL的开始。
1. 为什么学习string类
- C语言中的字符串
C语言中基本类型有char类型没有字符串类型,字符串是以'\0'结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数(如:strlen, strcmp,strcat,strcpy等),但是这些库函数与字符串是分离开的,不太符合OOP(面向对象)的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问。
因此为了更加高效的使用和管理字符串,C++提出了string类的概念,关于string类的学习我们先学习string类的使用,后面我们进一步深入时我们再去动手模拟实现string类,在这里我们首先知道string类的底层其实就是char类型的顺序表就行了。
2. 标准库中的string类
string类的文档介绍
从文档中我们能看到:

string类是basic_string模板类的一个实例,它使用char来实例化basic_string模板类。- string在底层实际是:basic_string模板类的别名,
typedef basic_string<char>string; - 不能操作多字节或者变长字符的序列。(如英文使用ASCII编码使用一个字节表示一个字母,汉字如果采用GBK编码占用两个字节表示一个汉字)
- 处理多字节或者变长字符的序列要用到以下三个类:

- 在使用string类时,必须包含
#include<string>以及using namespace std;
三、string类的常用接口说明
在上面的string类的文档介绍中我们可以看到string类接近有140个不同的接口函数,在这么多的成员函数中,很多都是冗余不必要的,因此下面我只讲解最常用的接口。
在讲解这些函数接口之前,我们先来介绍npos,npos是string类里面的一个静态成员变量,因此用string类创建的所有对象访问的都是同一个npos,其次我们来看pos的定义:

首先npos的值是被const修饰了,其值不能更改,然后size_t是无符号整形unsigned的typedef,定义将-1的值赋值给了npos,但npos是无符号整形,因此此时nops的值就是无符号整形的最大值65535。
1. string类对象的常见构造函数

- 缺省构造函数,用空字符串初始化string对象
- 拷贝构造函数,用
string类的对象另一个对象 - 用
string类的对象中的字符串的子串初始化一个对象,子串的起始位置是pos,结束位置是pos向后的len个字符,如果len没有给缺省值,默认为npos即从pos位置后面有多少拿多少。 - 用C风格的字符串初始化string类的对象
- 用C风格的字符串前n个字符初始化string类的对象
- 用n个字符初始化string类的对象
#include<iostream>
#include<string>
using namespace std;
int main()
{string s0("hello world!");string s1; //default (1) 缺省构造函数 //用空字符串初始化s1对象 string s2(s0); //copy (2) 拷贝构造函数 //用string类的对象s0初始化s2对象string s3(s0, 6, 5); //substring (3) 用string类的对象s0的字符串的子串"world"初始化s3 //这里pos参数表示位置,len表示的是个数string s4("hello string"); //from c-string (4) //C风格的字符串初始化string类的对象s4string s5("hello world",5); //from sequence(5) //用C风格的字符串前五个字符"hello"初始化string类的对象s5string s6(5, 'x'); //fill (6) //用5个'x'初始化string类的对象s6cout << s0 << endl;cout << s1 << endl;cout << s2 << endl;cout << s3 << endl;cout << s4 << endl;cout << s5 << endl;cout << s6 << endl;
}

2. string类对象的容量操作

- 我们先来看看不涉及扩容的函数
#include<iostream>
#include<string>
using namespace std;
int main()
{string s1("hello world");cout << s1.size() << endl;cout << s1.length() << endl;cout << s1.capacity() << endl;cout << s1.max_size() << endl;s1.clear();cout << s1.empty() << endl;return 0;
}

- 我们再来看看涉及扩容的函数
std::string::reserve()函数与std::string::shrink_to_fit()函数
//std::string::reserve()函数
#include<iostream>
#include<string>
using namespace std;
int main()
{string s1("hello world");cout << s1.size() << endl;cout << s1.capacity() << endl;s1.reserve(200); //提前把空间扩容到200字节,但不初始化//由于string类内部的一些原因(如:对齐等原因),虽然向系统申请的的200字节,//但不一定就是200字节,总之系统申请的空间会 >= 你给的指定值cout << s1.size() << endl;cout << s1.capacity() << endl;s1.shrink_to_fit(); //缩减容量让 size == capacitycout << s1.size() << endl;cout << s1.capacity() << endl;return 0;
}

观察会发现,经过reserve()函数的处理后size(字符个数)没有变,但是capacity(容量)改变了。
经过shrink_to_fit()函数处理后size(字符个数)没有变,但是capacity(容量)改变了。(虽然,shrink_to_fit()函数能够减少空间的浪费,但是我们还是一般不缩容,因为缩容的消耗是很大的)
- 我们再来看另一个扩容有关的函数:
std::string::resize()函数

此函数有两个版本,这两个版本构成函数重载。
第一个参数是:调整后容量的大小,第二个参数是用什么字符来初始化新申请的空间中多余的没有被初始化部分空间,如果不给此参数,就默认用’\0’来初始化。
如果第一个参数给的没有原来的大,那就是缩容,里面的字符串就变成了只保留原先字符串从0位置开始到n位置的字符串。
//std::string::resize()函数
#include<iostream>
#include<string>
using namespace std;
int main()
{string s1("hello world");cout << s1.size() << endl;cout << s1.capacity() << endl;s1.resize(30); //提前把空间与字符数量扩容到50字节,但不初始化//由于string类内部的一些原因(如:对齐等原因),虽然向系统申请的的50字节,//但不一定就是50字节,总之系统申请的空间会 >= 你给的指定值cout << s1.size() << endl;cout << s1.capacity() << endl;return 0;
}


注意:
- size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一致,一般情况下基本都是用size()。
- clear()只是将string中有效字符清空,不改变底层空间大小。
- 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 n=0):为string预留空间,不改变有效元素个数,当reserve的参数小于string的底层空间总大小时,reserver不会改变容量大小。
3. string类对象的单个元素访问

//string 里面关于单个元素的访问
#include<iostream>
#include<string>
using namespace std;
int main()
{string s1("hello world!");char ch1 = s1[1]; //operator[]的运算符重载char ch2 = s1[2]; //operator[]的运算符重载char ch3 = s1.at(6);cout << ch1 << endl;cout << ch2 << endl;cout << ch3 << endl;cout << "---------------" << endl;cout << s1.front() << endl;cout << s1.back() << endl;cout << "---------------" << endl;//捕获异常try{s1.at(100);}catch (const std::exception& e){//显示异常原因cout << e.what() << endl;}return 0;
}

4. string类对象的元素的遍历
对于string类对象的遍历有以下四种方式:

- 第一种
operator运算符重载我们已经学会了,我们可以利用如下代码进行遍历字符串:
#include<iostream>
#include<string>
using namespace std;
int main()
{string s1("hello world");for (int i = 0; i < s1.size(); ++i){cout << s1[i];}cout << endl;return 0;
}

- 第二种
beginend就需要借助STL里面的迭代器了,iterator是迭代器类型,是一种自定义类型,现在你可以暂时把它理解为类似于指针的类型。
想要遍历字符串我们就应该这样遍历:

#include<iostream>
#include<string>
using namespace std;
int main()
{string s1("hello world");string::iterator it = s1.begin();while (it != s1.end()){cout << *it;++it;}cout << endl;return 0;
}

- 第三种是
rbeginrend它们其实也是迭代器,不同的是,它们是反向迭代器,所以我们应该这样写才能遍历string对象。
#include<iostream>
#include<string>
using namespace std;
int main()
{string s1("hello world");string::reverse_iterator it = s1.rbegin();while (it != s1.rend()){cout << *it;++it;}cout << endl;return 0;
}

- 第三种是范围
for,在前面的文章中我们也谈论过范围for,利用范围for,也可以遍历string类(范围for的底层实现就是迭代器)。
#include<iostream>
#include<string>
using namespace std;
int main()
{string s1("hello world");for (auto& e : s1){cout << e;}cout << endl;return 0;
}

在前面已经简单的介绍了两种迭代器,(正向迭代器与反向迭代器)下面我们就把另外两种迭代器进行简单介绍补充:
const_iterator类型的迭代器
此类型的迭代器,不能通过迭代器来改变指向的对象里的内容。
#include<iostream>
#include<string>
using namespace std;
int main()
{const string s1("hello world");string::const_iterator it = s1.begin();while (it != s1.end()){(*it)++; //此行为非法!it++; //此行为合法!}return 0;
}
const_reverse_iterator类型的迭代器
此类型的迭代器是反向迭代器,并且不能通过迭代器来改变指向的对象里的内容。
#include<iostream>
#include<string>
using namespace std;
int main()
{const string s1("hello world");string::const_reverse_iterator it = s1.rbegin();while (it != s1.rend()){(*it)++; //此行为非法!it++; //此行为合法!}return 0;
}
5.string类对象的修改操作


#include<iostream>
#include<string>
using namespace std;
int main()
{string s0("hello ");string s1("world");s0 += s1;cout << s0 << endl;s0 += " string";cout << s0 << endl;s0 += '!';cout << s0 << endl;return 0;
}


#include<iostream>
#include<string>
using namespace std;
int main()
{string s0("hello ");string s1("world");//substring (2)s0.append(s1, 0, 3);cout << s0 << endl;//buffer (4) s0.append("string", 3);cout << s0 << endl;//fill (5)s0.append(5, '!');cout << s0 << endl;return 0;
}


#include<iostream>
#include<string>
using namespace std;
int main()
{string s0("hello ");s0.push_back('!');cout << s0 << endl;
}


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

#include<iostream>
#include<string>
using namespace std;
int main()
{string s0("hello ");string s1("world");//string (1) s0.insert(0, s1);cout << s0 << endl;//c-string (3) s0.insert(3, "!!!!!!");cout << s0 << endl;
}


#include<iostream>
#include<string>
using namespace std;
int main()
{string s0("hello ");s0.erase(2, 2);cout << s0 << endl;
}


#include<iostream>
#include<string>
using namespace std;
int main()
{string s0("hello ");//c-string (3)s0.replace(2, 2,"!!!!!");cout << s0 << endl;
}


#include<iostream>
#include<string>
using namespace std;
int main()
{string s0("hello ");string s1("world");s0.swap(s1);cout << s0 << endl;cout << s1 << endl;return 0;
}


#include<iostream>
#include<string>
using namespace std;
int main()
{string s0("hello");s0.pop_back();cout << s0 << endl;return 0;
}

6.string类对象的一些其他操作


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


#include<iostream>
#include<string>
using namespace std;
int main()
{string s1("hello world");/*const char* str1 = s1.c_str();cout << str1 << endl;*/char ch = 'a';char* str1 = &ch;s1.copy(str1, 3, 2); // 注意此函数不会拷贝完后追加字符串,打印字符串时要小心越界。return 0;
}

#include<iostream>
#include<string>
using namespace std;
int main()
{//buffer (3) string s1("hello world");const char* str = "world";int index = s1.find(str, 0, 3);cout << index << endl;return 0;
}


#include<iostream>
#include<string>
using namespace std;
int main()
{//c-string (2) string s1("hello world");const char* str = "world";int index = s1.rfind(str);cout << index << endl;return 0;
}


#include<iostream>
#include<string>
using namespace std;
int main()
{string s1("hello world");int index = s1.find_first_of("wor");cout << index << endl;return 0;
}


#include<iostream>
#include<string>
using namespace std;
int main()
{string s1("hello world");string s2 = s1.substr(2, 3);cout << s2 << endl;return 0;
}


#include<iostream>
#include<string>
using namespace std;
int main()
{//string (1) string s1("hello world");string s2("iello");cout << s1.compare(s2) << endl;return 0;
}

7.getline函数
getline的作用是读取一整行,直到遇到换行符才停止读取,期间能读取像空格、Tab等的空白符。

getline函数和cin一样,也会返回它的流参数,也就是cin,所以可以用getline循环读取带空格的字符串。
注意: getline 是非成员函数!
#include<iostream>
#include<string>
using namespace std;
int main()
{string s1;//这里我们输入"hello world!"getline(cin, s1);cout << s1 << endl;return 0;
}

四、结语
本章的内容都不是很难,但是琐碎的函数与细节特别多,想要掌握好它们还需要多加练习。多去使用它们,相信你会越用越熟悉的。
相关文章:
【C++】C++标准模板库STL (一) string类的使用详解
前言 在前一章种我们介绍了C中的模板的使用,这是一种泛型编程,模板的使用能让我们减少大量的相似代码,减少我们的代码量与工作量,写出更加高效简洁的代码,模板如此好用,但还是要我们先出写一个泛型类或函数…...
如何用SpringBoot+Thymeleaf+Echart生成好看的柱状图,折线图,饼状图
一、前言 上篇文章我们用POI技术读取Excel并生成了相应的图表。但是实际的效果比较一般,因为本身WPS生成图表就比较简单,如果用程序操作远比人工耗时费力,效果远不如一些付费模板。如下图所示: 然后我就想到前端不是有一个简单易…...
LeetCode819. 最常见的单词(python)
题目 给定一个段落 (paragraph) 和一个禁用单词列表 (banned)。返回出现次数最多,同时不在禁用列表中的单词。 题目保证至少有一个词不在禁用列表中,而且答案唯一。 禁用列表中的单词用小写字母表示,不含标点符号。段落中的单词不区分大小写。…...
【深入理解C指针】经典笔试题——指针和数组
🔹内容专栏:【C语言】进阶部分 🔹本文概括:一些指针和数组笔试题的解析 。 🔹本文作者:花香碟自来_ 🔹发布时间:2023.3.12 目录 一、指针和数组练习题 1. 一维数组 2. 字符数组 …...
雷达散射截面
雷达散射截面(Radar Cross Section, RCS)是表征目标散射强弱的物理量。 σ = 4 π R 2 ∣ E s ∣ 2 ∣ E i ∣ 2 \sigma = 4\pi R^2 \frac{|E_s |^2}{|E_i|^2}...
希腊棺材之谜——复盘
文章目录梗概推导伪解答虽然花费6-8小时来看小说,是一件很奢侈的事情。但是再荒诞的事情终归有它背后的逻辑链条。这正如Ellery所坚持的那样,逻辑为王。希腊棺材之谜是Ellery Queen首次展露头角, 因此作者特地给他安排了3次伪解答和1次真解答…...
CentOS的下载和安装
文章目录前言一、CentOS的下载二、如何下载1.选择下载版本2.选择isos3.点击isos后,进入如下页面,接着点击X86_644.一般选择下面框住的进行下载三、安装软件选择设置接着进行分区设置设置网络和主机名前言 在学习Linux时,记录下CentOS的安装 …...
new bing的chatGPT如何解析英文论文pdf
昨天我的new bing申请下来了,有了聊天的界面: 但是解析pdf的英文文献,还是不行,没有对话窗口。就问了一下chatGPT,方案如下: 要使用New Bing解析PDF文献,你需要以下几个步骤: 1&a…...
学会这12个Python装饰器,让你的代码更上一层楼
学会这12个Python装饰器,让你的代码更上一层楼 Python 装饰器是个强大的工具,可帮你生成整洁、可重用和可维护的代码。某种意义上说,会不会用装饰器是区分新手和老鸟的重要标志。如果你不熟悉装饰器,你可以将它们视为将函数作为输…...
企业使用ERP的好处
ERP系统是企业管理信息系统的简称,它是以信息技术为手段,以物流、资金流、信息流为主线,以企业的核心业务流程为对象,建立的一套适用于企业管理的、高效的企业管理信息系统。它是通过科学方法和计算机信息技术,将企业运…...
【QT】如何获取屏幕(桌面)的大小或分辨率
目录1. QDesktopWidget 获取系统屏幕大小2. QScreen 获取系统屏幕大小3. geometry() 与 availableGeometry() 的区别1. QDesktopWidget 获取系统屏幕大小 QDesktopWidget 提供了详细的位置信息,其能够自动返回窗口在用户窗口的位置和应用程序窗口的位置 QDesktopW…...
ETL工具的选择
正确选择 ETL 工具,可以从 ETL 对平台的支持、对数据源的支持、数据转换功能、管理 和调度功能、集成和开放性、对元数据管理等功能出发,具体如下。 支持平台 随着各种应用系统数据量的飞速增长和对业务可靠性等要求的不断提高,人们对数据抽…...
SpringBoot仿天猫商城java web购物网站的设计与实现
1,项目介绍 基于 SpringBoot 的仿天猫商城拥有两种角色,分别为管理员和用户。 迷你天猫商城是一个基于SSM框架的综合性B2C电商平台,需求设计主要参考天猫商城的购物流程。 后端页面兼容IE10及以上现代浏览器,Chrome,Edge,Firebox…...
C#基础教程22 文件的输入与输出
C# 文件的输入与输出 一个 文件 是一个存储在磁盘中带有指定名称和目录路径的数据集合。当打开文件进行读写时,它变成一个 流。 从根本上说,流是通过通信路径传递的字节序列。有两个主要的流:输入流 和 输出流。输入流用于从文件读取数据(读操作),输出流用于向文件写入数…...
Ubuntu18.04 python 开发usb通信
一、安装环境 1.安装pip sudo python3 get-pip.py 或 sudo -i apt update apt install python3-pip 确定pip是否安装成功: xxx-desktop:~$ pip3 --versionpip 9.0.1 from /usr/lib/python3/dist-packages (python 3.6)2.安装pyusb pip3 install pyusb --use…...
RabbitMq 消息确认机制详解 SpringCloud
1 消息可靠性 消息从发送,到消费者接收,会经理多个过程,其中的每一步都可能导致消息丢失. #### 2 常见的丢失原因 发送时丢失: 生产者发送的消息未送达exchange 消息到达exchange后未到达queueMQ宕机,queue将消息丢失 consumer…...
后台导航布局
五、后台导航实例 参考链接: 页面后台导航制作 如何实现html后台导航iframe点击换url(代码) 如何消除html页面下边和右边的滚动条 html页面有多个滚动条时的优化 页面出现不必要的滚动条,怎么调试? 一个页面有两…...
设计模式——抽象工厂模式(创建型)
一、介绍抽象工厂模式是一种创建型设计模式, 它能创建一系列相关的对象, 而无需指定其具体类。问题假设你正在开发一款家具商店模拟器。 你的代码中包括一些类, 用于表示:一系列相关产品, 例如 椅子Chair 、 沙发Sofa和…...
Java面试题--SpringMVC的执行流程
概要 SpringMVC是一种基于MVC(Model-View-Controller)框架的Web应用开发框架。下面是SpringMVC的详细执行流程。 客户端向DispatcherServlet发送请求。DispatcherServlet收到请求后,根据HandlerMapping(处理器映射)找…...
c# 32位程序突破2G内存限制
起因 在开发过程中,由于某些COM组件只能在32位程序下运行,程序不得不在X86平台下生成。而X86的32位程序默认内存大小被限制在2G。由于程序中可能存在大数量处理,期间对象若没有及时释放或则回收,内存占用达到了1.2G左右ÿ…...
华为云AI开发平台ModelArts
华为云ModelArts:重塑AI开发流程的“智能引擎”与“创新加速器”! 在人工智能浪潮席卷全球的2025年,企业拥抱AI的意愿空前高涨,但技术门槛高、流程复杂、资源投入巨大的现实,却让许多创新构想止步于实验室。数据科学家…...
如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...
Frozen-Flask :将 Flask 应用“冻结”为静态文件
Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是:将一个 Flask Web 应用生成成纯静态 HTML 文件,从而可以部署到静态网站托管服务上,如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...
DBAPI如何优雅的获取单条数据
API如何优雅的获取单条数据 案例一 对于查询类API,查询的是单条数据,比如根据主键ID查询用户信息,sql如下: select id, name, age from user where id #{id}API默认返回的数据格式是多条的,如下: {&qu…...
04-初识css
一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...
BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...
uniapp中使用aixos 报错
问题: 在uniapp中使用aixos,运行后报如下错误: AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...
vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...
Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...
