C++ STL:string类的概述及常用接口说明
目录
一. 什么是STL
二. string类的概述
三. string类的常用接口说明
3.1 字符串对象创建相关接口(构造函数)
3.2 字符串长度和容量相关接口
3.3 字符访问相关接口函数
3.4 字符串删改相关接口函数
3.5 字符查找和子串相关接口函数
3.6 迭代器相关接口函数
3.7 常用的关于string类对象的全局函数
一. 什么是STL
STL,即标准库模板(standard template library),是C++标准库的重要组成部位,是一个包含了很多经常使用的数据结构和算法的软件框架。
C++标准规定的STL有六大组件:容器、迭代器、算法、仿函数、空间配置器和配接器,其中容器就是我们常说的数据结构。

二. string类的概述
string类,是专为用于存储和操作字符串的类,使用STL string容器的接口,可以实现对字符串进行增删查改、计算长度、循环遍历等操作。string类是模板类basic_string以char为模板参数类型的一个实例,其定义为:typedef basic_string<char> string。
那么或许会有人问:字符串的每个字符不都是char类型吗,那么直接将basic_string的参数类型定义为char不就行了吗,为什么还要定义模板再实例化?
其实,我们通常认为的char类型仅仅可以表示英文字母或字符,每个char类型数据的值,通过编码表(通常为ASCII码表)与特定字符对应,由于英文字母仅有26个,加上各种可打印字符不过128个,char类型数据完全足够对英文进行编码。
但是,其他语言就不一样了,中文汉字有几万几十万,char类型数据是无法表示的。因此,为了对汉字进行编码,就引入wchar_t型数据,一个wchar_t型数据占2byte,可以表示60000多个汉字,基本可以涵盖所有常见汉字。
因此,basic_string之所以不直接将成员变量类型设为char而是采用模板,就是为了能够实例化出不同类型的模板参数,以对应不同的编码规则,从而使其适用于全世界的语言。
常见的编码规则
编码:通过值与符号表建立映射关系,从而使值可以转换为各种字符。
- ASCII码 -- 适用于英文。
- unicode -- 全世界文字的通用编码表,又称万国码。它为世界各国语言的每个字符设置了统一且唯一的二进制编码。unicode下面有包括utf-8、utf-16、utf-32这几种细化的编码规则,他们分别表示以无符号的8、16、32个二进制位的数据进行编码。
- gkb -- 为中文量身定制的编码表。
在Windows下,中文采用gkb编码规则,长字节w_char类型数据可用于中文编码。
三. string类的常用接口说明
3.1 字符串对象创建相关接口(构造函数)
- string() -- 创建空字符串对象(仅包含字符串结束标识\0)。
- string(const string& s) -- 拷贝构造,通过一个string类对象创建一个新的string类对象。注意string类的拷贝构造函数完成的是深拷贝,他会为新创建的对象再开辟一块内存空间,用于存储与s对象相同的字符,即:两者表示的字符串内容相同,但并不是存储在同一块空间的字符串。
- string(const char* s) -- 通过一个现有的字符串构造string类对象。
- string(const string& s, size_t pos, size_t len = npos) -- 通过一个string类对象的子字符串构建新的对象,子串的为:从下标pos开始为第一个字符,向后len个字符。缺省参数npos为string类的静态成员变量,值为size_t类型的-1(一个极大的数)。如果pos往后的字符数不足len,那么就用从pos往后的所有字符创建对象。
- string(const char* s, size_t n) -- 用字符串s的前n个字符构建字符串。
演示代码3.1:
int main()
{string s1; //空字符串构建string s2("abcdef"); //通过字符串创建对象string s3(s2); //通过拷贝构造创建新对象string s4(s2, 1, 3); //通过已有类对象的子串创建新对象 -- "bcd"string s5("abcdef", 3); //通过字符串的前n个字符创建新对象 -- "abc"cout << "s1 = " << s1 << endl;cout << "s2 = " << s2 << endl;cout << "s3 = " << s3 << endl;cout << "s4 = " << s4 << endl;cout << "s5 = " << s5 << endl;return 0;
}

3.2 字符串长度和容量相关接口
- size -- 获取字符串长度(不包括末尾\0),函数原型为:size_t size() const。
- length -- 获取字符串长度(不包括末尾\0),函数原型为:size_t length() const。
在string类中,size和length没有任何区别。但是,size可以用在树、链表等其他数据结构中计算数据量,而length不行。为了保证STL中各种数据结构的接口名称统一,一般建议使用size。
- capacity -- 获取当前string类对象能够存储的有效字符量,函数原型为:size_t capacity() const。
- reserve -- 将字符串空间扩容到至少一定的值,函数原型为:void reserve(size_t n)。用reserve进行扩容,并一定恰好扩容到n,而是扩容到不小于n。同时,reserve不影响字符串中原来的内容,且不对扩大的那部分空间进行初始化,如果n小于原来的capacity,那么reverse函数不进行任何工作。
- resize -- 使字符串的长度(size\length)变到n,函数原型为:void resize(size_t n)、void resize(size_t n, char ch),这两个函数构成重载。resize函数的工作为:将函数长度扩大到n,在将扩大的部分的内容改为ch,如果不给定ch值,则默认为'\0'。如果n小于原来的长度size,那么就截取前n个内容。
- clear -- 清空字符串的内容,使字符串的长度(size\length)变为0。
- empty -- 判断字符串是否为空。
演示代码3.2:
int main()
{string s1("abc");cout << "size = " << s1.size() << endl;cout << "length = " << s1.length() << endl; //获取s1的长度cout << "capacity = " << s1.capacity() << endl; //获取s1的容量cout << endl;s1.resize(10, 'x');cout << "s1 = " << s1 << endl; //abcxxxxxxxcout << "size = " << s1.size() << endl; //10cout << endl;s1.reserve(20); //将s1的容量扩大到至少20cout << "capacity = " << s1.capacity() << endl; // >=20cout << "size = " << s1.size() << endl; //3cout << endl;cout << s1.empty() << endl; //非0s1.clear(); //清空数据cout << s1.empty() << endl; //0cout << "size = " << s1.size() << endl; //0cout << "capacity = " << s1.capacity() << endl; //31return 0;
}

3.3 字符访问相关接口函数
- [] -- 下标引用操作符重载:char& operator[](size_t pos)、const char& operator[](size_t pos) const,两个函数构成重载,分别用于访问普通类对象和const类对象。
- at -- 访问指定下标位置处的字符:char& at(size_t pos)、const char& at(size_t pos) const。
重载[]和at都可以达到访问某个下标位置处字符的目的,但是,当出现越界访问时,[]会assert断言出错,at会抛异常,且[]更符合一般的编码习惯,这里推荐使用[]而不是ar。
演示代码3.3:
int main()
{string s1("abcdef");const string s2("abcdef");//使用[],将s1的每个值+1for (size_t i = 0; i < s1.size(); ++i){s1[i] += 1;}cout << s1 << endl; //bcdefg//[]访问const对象s2的每个字符,只能读不能写for (size_t i = 0; i < s2.size(); ++i){//s2[i] += 1; //报错cout << s2[i];}cout << endl;//通过at函数,遍历打印s2的每个字符for (size_t i = 0; i < s2.size(); ++i){cout << s2.at(i);}cout << endl;return 0;
}

3.4 字符串删改相关接口函数
- operator+= -- 尾插字符或字符串
- string& operator+=(const string& s) -- 通过类对象获取尾插字符串
- string& operator+=(const char* s) -- 直接尾插字符串s
- string& operator+=(char c) -- 尾插字符c
- push_back -- 尾插字符。函数原型为:void push_back(char c)
- append -- 尾插字符串或字符
- string& append(const string& s) -- 通过string类对象获取字符串尾插
- string& append(const char* s) -- 直接尾插字符串
- string& append(const string& s, size_t pos, size_t len = npos) -- 通过获取子字符串尾插
- string& append(const char* s, size_t n) -- 尾插字符串s的前n个字符
- insert -- 在指定位置插入字符或字符串
- string& insert(size_t pos, const string& s) -- 在pos下标处通过string类对象插入字符串
- string& insert(size_t pos, const string& s, size_t subpos, size_t len = npos) -- 在pos位置处插入string对象的一个子字符串
- string& insert(size_t pos, const char* s) -- 在pos下标处插入字符串s
- string& insert(size_t pos, const char* s, size_t n) -- 在pos下标处插入s的前n个字符
- string& insert(size_t pos, size_t n, char c) -- 在pos位置处插入n个c字符
- erase -- 从指定位置开始删除n个字符,函数原型:string& erase(size_t pos = 0, size_t len = npos)
演示代码3.4:
int main()
{string s1;s1 += "aaa"; //+=尾插字符串cout << s1 << endl;s1 += 'b'; //+=尾插单个字符cout << s1 << endl;s1.push_back('c'); //push_back尾插单个字符cout << s1 << endl;s1.append("ddd"); //append尾插字符串cout << s1 << endl;cout << endl;string s2("aaaaaaa");s2.insert(2, "bbbb"); //在下标2的位置插入字符串"bbbb"cout << s2 << endl;s2.erase(2, 4); //从下标为2的位置开始删除4个字符cout << s2 << endl;return 0;
}

3.5 字符查找和子串相关接口函数
- c_str -- 获取string类对象中的字符串成员(字符串首字符地址)。函数原型为:const char* c_str() const。
- find -- 以指定下标位置pos为起点,从前向后查找特定字符或子字符串,找到了返回字符或子串第一次出现的下标,找不到就返回npos。
- size_t find(const string& s, size_t pos = 0) const -- 查找sting对象s的字符串。
- size_t find(const char* s, size_t pos = 0) const -- 查找字符串s。
- size_t find(const char* s, size_t pos, size_t len) const -- 查找字符串s的一个子串。
- size_t find(char c, size_t pos = 0) const -- 查找字符c。
- refind -- 与find类似,从尾部开始,查找子字符串或字符第一次出现的下标位置。
- substr -- string substr(size_t pos = 0, size_t len = npos) -- 从当前string对象中获取子串,构建一个新的string对象。
演示代码3.5:
int main()
{string s1("abcdefgh");cout << s1.c_str() << endl; //获取字符串成员cout << s1.find("bcd") << endl; //查找子串"bcd" -- 输出1cout << s1.find("cdeg", 2, 3) << endl; //从下标2处开始查找"cdef"前3个字符构成的子串"cde" -- 输出2cout << s1.find('e') << endl; //查找字符e -- 输出4cout << endl;string s2("abcdefabcdef");cout << s2.rfind("abc", 9) << endl; //查找下标位置9之前pos最后一次出现的位置 -- 输出6cout << s2.rfind('e') << endl; //查找字符'e'最后一次出现的位置 -- 输出10string s3("abcdef");string s4 = s3.substr(1, 4);cout << "s4 = " << s4 << endl; //bcdereturn 0;
}

3.6 迭代器相关接口函数
迭代器的类型为iterator,是char*的类型重定义名称,其定义语句为:typedef char* iterator -- 对于普通对象的迭代器,typedef const char* const_iterator -- 对于const属性对象的迭代器。除了一般的iterator以外,还有反向迭代器reverse_iterator和const_reverse_iterator。
对iterator类型的变量执行++操作,其指向的位置后移一位、对reverse_iterator类型的成员变量执行++操作,其指向的位置前移一位。
- begin -- 获取指向字符串首元素的指针,函数原型为:iterator begin()和const_iterator begin() const,这两个函数构成重载,分别应用于普通对象和const属性对象。
- end -- 获取指向字符串最后一个元素后面那个位置('\0')的指针,函数原型为:iterator end()和const_iterator end() const。

- rbegin -- 返回指向字符串最后一个字符的指针,函数原型为:reverse_iterator rbegin() 和 const_reverse_iterator rbegin() const。
- rend -- 返回指向字符串第一个字符前一个位置的指针,函数原型为:reverse_iterator rend() 和 const_reverse_iterator rend() const。

演示代码3.6:
int main()
{string s1("abcde");//使用正向迭代器遍历s1的每个字符,+1后输出string::iterator it1 = s1.begin();while (it1 != s1.end()){++(*it1);cout << *it1; //输出bcdef++it1;}cout << endl;string s2("abcde");//使用反向迭代器,反向遍历s2的每个字符并输出string::reverse_iterator it2 = s2.rbegin();while (it2 != s2.rend()){cout << *it2; //输出edcba++it2;}cout << endl;return 0;
}

3.7 常用的关于string类对象的全局函数
在C语言阶段,学过函数atoi,功能是将字符串转化为整数。但是,C/C++标准库函数中并没有atoi函数,虽然大部分编译器都已支持atoi函数,但是,依然建议不要使用,这样会降低程序的可移植性,很多老式编译器依然不支持atoi。
- stoi -- 将string类对象转换为int型数据。
- stol -- 将string类对象转换为long int型数据。
- stoul -- 将string类对象转换为unsigned long int型数据。
- stoll -- 将string类对象转换为long ong型数据。
- stoull -- 将string类对象转换为转换为unsigned long long型数据。
- stof -- 将string类对象转换为float型数据。
- stod -- 将string类对象转换为double型数据。
上述函数,会自动排除字符串前部的空格,会通过'+'、'-'字符判断返回值的正负,当遇到非数字字符时,函数会终止执行,返回当前值。
注意:如果string无法转换为数字(首个非空字符不是'+'、'-'或数字字符),以及超出数据类型表示范围的情况下,上述函数均会抛异常,引发程序崩溃。
演示代码3.7:
int main()
{string s1(" -123ab1");string s2(" 1234");string s3("+1234abc");string s4("aa");string s5("-123.12");string s6("100.111abc");string s7("110.ab");string s8("001234.5");string s9("123456789987654321");cout << "s1 = " << stoi(s1) << endl; //-123cout << "s2 = " << stoi(s2) << endl; //1234cout << "s3 = " << stoi(s3) << endl; //1234//cout << "s4 = " << stoi(s4) << endl; //无法转换为int会抛异常cout << "s5 = " << stod(s5) << endl; //-123.12cout << "s6 = " << stod(s6) << endl; //110.111cout << "s7 = " << stod(s7) << endl; //110cout << "s8 = " << stod(s8) << endl; //1234.5//cout << "s9 = " << stoi(s9) << endl; //超出int范围会抛异常return 0;
}
相关文章:

C++ STL:string类的概述及常用接口说明
目录 一. 什么是STL 二. string类的概述 三. string类的常用接口说明 3.1 字符串对象创建相关接口(构造函数) 3.2 字符串长度和容量相关接口 3.3 字符访问相关接口函数 3.4 字符串删改相关接口函数 3.5 字符查找和子串相关接口函数 3.6 迭代器相…...

java Math类 和 System类 详解(通俗易懂)
Math类介绍Math类常用方法及演示System类简介System类常用方法及演示一、前言本节内容是我们《API-常用类》专题的第四小节了。本节内容主要讲Math类和System类, 内容包括Math类介绍、Math类常用方法、System类介绍,System类常用方法。该小节内容基本不涉…...

软件回归测试是什么?
一、软件回归测试是什么? 软件回归测试作为软件生命周期的一个组成部分,在整个软件测试过程中占有很大的工作量比重,软件开发的各个阶段都会进行多次回归测试。回归测试是指修改了旧代码后,重新进行测试以确认修改没有引入新的错误或导致其…...

TwinCAT3中ModbusTCP Server和C# Client连接
目录 一、硬件环境 1、设置PLC的ip地址 2、ModbusTCP软件安装 3、PLC操作系统防火墙设置 4、网络助手连接PLC 二、创建PLC工程 1、创建寄存器读写变量 2、添加ModbusTCP授权 3、激活和运行工程 三、ModbusTCP数据协议说明 1、写单个寄存器 2、读寄存器 (1&…...

【上传项目代码到Git详细步骤】
1.下载安装Git到电脑上(这里我之前已经安装好了,就不细说了)2.进入控制台安装好后右键点击桌面空白部分会多出两个菜单选项,点击第二个Git Bash Here(点击第一个你会爆炸)会弹出一个git控制台,如…...

C++回顾(十五)—— 类模板
15.1 为什么要有类模板 类模板用于实现类所需数据的类型参数化类模板在表示如数组、表、图等数据结构显得特别重要,这些数据结构的表示和算法不受所包含的元素类型的影响 15.2 单个类模板语法 注意:类模板的创建对象一定要显示调用(指明类型…...

【JavaEE初阶】第四节.文件操作 和 IO (下篇)
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言三、文件内容的操作 3.1 读文件 3.1.1 使用字节流读文件 3.2 写文件 3.2.1 使用字节流写文件 …...

华为OD机试用Python实现 -【分解质因数】 2023Q1A
华为OD机试题 本篇题目:分解质因数题目示例 1输入输出示例 2输入输出Code代码编写思路最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为机试题 | 机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南...

博客项目
文章目录1. 创建项目2. 数据库设计3. 前置任务3.1 拦截器3.2 统一数据格式3.3 创建一个 Constant3.4 统一异常处理3.5 密码加密4. 功能实现4.1 登录功能4.2 注册功能4.3 博客列表页 (功能实现)4.3.1 左侧框4.3.2 右侧框 (分页功能 页面显示)4.4 博客详情…...

C++基础了解-20-C++类 对象
C 类 & 对象 一、C 类 & 对象 C 在 C 语言的基础上增加了面向对象编程,C 支持面向对象程序设计。类是 C 的核心特性,通常被称为用户定义的类型。 类用于指定对象的形式,它包含了数据表示法和用于处理数据的方法。类中的数据和方法…...

多态与虚(函数)表
前言续接上回(继承),我们了解了继承是如何通过虚基表,来解决派生类和父类有相同的成员变量的情况,但是类和对象中可不只有成员变量,如果成员函数也有同名,更或者如果我们想在访问不同情况&#…...

云舟案例︱视频孪生技术赋能城市安全综合管理场景,提升城市数智化水平
随着城市化发展进程的加快,人口不断膨胀,社会安全隐患等问题日益突出,成为困扰城市建设与管理的重要难题。针对各类社会治安突出问题,城市管理部门积极推进城市信息化建设,视频监控等各类信息化采集手段为城市数字化管…...
OpenFOAM 自定义gcc和openmpi安装
Compile Logs 编译很多次了但是好久不编还是会容易遗漏细节步骤,谨以为记。 使用自己编译的编译器和openmpi而不是系统自带的 库来完成对OF 的编译 依赖包安装 编译 GCC 编译 openmpi 编译OF 1依赖包安装 先 sudo apt-get install update当然,然后安…...

2023年3.8女神节买台灯怎么挑选?台灯用什么样的比较好
最近女神节,祝广大女性朋友们节日快乐啊。娱乐之余,一些实用的东西也是非常适合作为礼物送给女性朋友哦,台灯就是其中一个不错的选择。 台灯作为一种智能家居产品,不仅可见点缀卧室房间装饰,晚上的时候开启小范围照明&…...

近亿美元:人工心脏龙头永仁心医疗完成超大额A轮融资
近日,永仁心医疗器械有限公司(以下简称“永仁心医疗”)完成近一亿美元A轮融资,由北京科兴中维生物技术有限公司(SINOVAC科兴)领投,太平(深圳)医疗健康产业私募股权投资基…...

群智能优化计算中的混沌映射
经实验证明,采用混沌映射产生随机数的适应度函数值有明显提高,用混沌映射取代常规的均匀分布的随机数发生器可以得到更好的结果,特别是搜索空间中有许多局部解时,更容易搜索到全局最优解,利用混沌序列进行种群初始化、…...

【LeetCode】剑指 Offer 25. 合并两个排序的链表 p145 -- Java Version
题目链接:https://leetcode.cn/problems/he-bing-liang-ge-pai-xu-de-lian-biao-lcof/ 1. 题目介绍(25. 合并两个排序的链表) 输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的。 【测试用例】…...

如何应对危害机房安全的这几个常见要素?
随着现代化进程的推进,各行业对计算机的依赖性日益增高,计算机系统已经成为业务系统的重要组成部分。 在这种情况下,一旦机房设备出现故障,就会影响机房的正常运行,造成严重后果。尤其是银行、证券、海关等需要实时数据…...

【bug】antd全局的主题色样式被覆盖,被修改为`antd`默认的主题色
背景: 项目本身修改了主题色,配置如下: // umi配置文件 export default {theme: {primary-color: #2F54EB, // 全局主色}, };需要对图片上传组件做封装,并在项目中统一引用,如下 import { TdsUpload } from tdsComponents;环境信息 node tiandstiandsdeMacBook…...

MySQL DDL表操作【入门到精通】
目录 一、查询创建 1、查询当前数据库所有表 2、查看指定表结构 3、查询指定表的建表语句 4、创建表结构 二、数据类型 1、数值类型 2、字符串类型 3、日期时间类型 三、表操作-案例 设计一张员工信息表,要求如下: 对应的建表语句如下&#…...

linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...

【Oracle APEX开发小技巧12】
有如下需求: 有一个问题反馈页面,要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据,方便管理员及时处理反馈。 我的方法:直接将逻辑写在SQL中,这样可以直接在页面展示 完整代码: SELECTSF.FE…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了: 这一篇我们开始讲: 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下: 一、场景操作步骤 操作步…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...
Java多线程实现之Callable接口深度解析
Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...
ffmpeg(四):滤镜命令
FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...
ip子接口配置及删除
配置永久生效的子接口,2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...
2023赣州旅游投资集团
单选题 1.“不登高山,不知天之高也;不临深溪,不知地之厚也。”这句话说明_____。 A、人的意识具有创造性 B、人的认识是独立于实践之外的 C、实践在认识过程中具有决定作用 D、人的一切知识都是从直接经验中获得的 参考答案: C 本题解…...

JVM 内存结构 详解
内存结构 运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器: 线程私有,程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 每个线程都有一个程序计数…...

LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf
FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...