当前位置: 首页 > news >正文

[ C++ ] STL---string类的使用指南

目录

前言:

 string类简介

string类的常用接口

string类对象的构造函数

string类对象的赋值运算符重载

 string类对象的容量操作

string类对象的访问与遍历

[ ] + 下标遍历

迭代器遍历

普通迭代器iterator

​编辑 const迭代器const_iterator

反向迭代器reverse_iterator

范围for遍历

string类对象的修改操作

string类非成员函数


前言:

STL(standard template libaray-标准模板库):c++标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架

  • STL的六大组件

容器:各种数据结构,比如顺序表、链表、双端队列、集合 、映射等,主要用于存放数据;

算法:主要用于操作容器中数据的模版函数,如 sort(插入排序,快速排序,堆排序);

迭代器:提供遍历容器中数据的方法,迭代器是一种将operator*、operator->、operator++等指针的相关操作赋予重载的类模版;

仿函数:仿函数是重载了operator()运算符的一个类/结构体,使其可以像函数一样被调用;

适配器:专门用于修饰现有类的接口,提供一种新的接口;

空间配置器:负责空间的配置与管理,配置器是一个实现了动态空间配置,空间管理、空间释放的类模版;

 string类简介

string是由类模板basic_string实例化出来的一个类,string本质为动态增长的字符数组;

string类的官方文档:string - C++ Reference

注:使用string类时,必须包含头文件#include<string>以及使用using namespace std;

string类的常用接口

string类对象的构造函数


string();//无参构造(重点掌握)string (const string& str);//拷贝构造(重点掌握)string (const string& str, size_t pos, size_t len = npos);
//string类对象str的第pos个位置开始,向后拷贝len个字符初始化对象string (const char* s);//通过常量字符串s初始化对象(重点掌握)string (const char* s, size_t n);//字符串s的前n个字符初始化对象string (size_t n, char c); //n个字符c初始化对象template <class InputIterator> //迭代器区间构造string  (InputIterator first, InputIterator last);

  •  string::npos为静态成员变量,表示size_t的最大值;
  •  该值表示"直到字符串末尾",作为返回值它通常被用作表明没有匹配;

string类对象的赋值运算符重载

string& operator= (const string& str);//支持string类对象赋值string& operator= (const char* s);//支持常量字符串赋值string& operator= (char c);//支持单个字符赋值

 string类对象的容量操作

 size()与length()底层实现原理相同,皆返回字符串有效字符的长度(不包含'\0'),引入size()原因是为了与其他容器接口保持一致,一般情况下皆使用size()

 capacity()返回空间总大小,capacity()与size()大小可能相同,也有可能比size()更大;

 empty()检测字符串是否为空串,是返回true,否则返回false;

clear()将string类对象中的有效字符清空,不改变底层空间的大小;

 

reserve()为字符串预留空间,当reserve()的参数大于string的底层空间总大小时,reserve()只会改变capacity()的大小,但是具体扩容的容量取决于编译器,当reserve()的参数小于string的底层空间总大小时,reserve()什么都不做;

  • 扩容机制检测

vs平台下移1.5倍进行扩容,linux平台下以2倍进行扩容;

  •  n>capacity()时,扩容+尾插(指明字符c,尾插字符c,不指明字符,插入'\0')
  • size()<n<capacity()时,有效数据的个数size()改变为n,容量capacity()不确定,可能会扩容,可能不变;
  • n<size()时,容量capacity()不变,有效数据的个数size()改变为n,删除数据,保留前n个;

 

string类对象的访问与遍历

[ ] + 下标遍历

[ ]运算符重载返回字符串中下标为pos位置的字符的引用,重载[ ]运算符意味着string类对象可以像访问数组一样利用下标访问元素;

  char& operator[] (size_t pos); //可读可写
const char& operator[] (size_t pos) const //只读

若只实现const char& operator[] (size_t pos) const,则const对象可以调用此const成员函数,非const对象也可以调用此const成员函数,因为权限可以缩小;但是非const对象无法修改返回值,诞生函数重载形式 char& operator[] (size_t pos);

迭代器遍历

普通迭代器iterator
//string的底层物理结构
class string
{
public://迭代器的本质为重命名过的指针变量typedef char* iterator;//成员函数
private:char* _str;size_t _size;size_t _capacity;
};

 begin()函数返回string类对象的首位置;

end()函数返回string类对象的最后一个有效数据的下一个位置;

 const迭代器const_iterator
const_iterator begin() const;const_iterator end() const;
  1. const_iterator  本质为保护迭代器指向的内容不允许被修改
  2. const  iterator  本质为保护迭代器本身不允许被修改

反向迭代器reverse_iterator

范围for遍历

string类对象的修改操作

string类的修改接口设计的十分冗余,其中可以使用 operator += 替代append()与push_back(),因此只需重点学习 operator +=;

int main()
{string tmp("hello Linux!");string s1;// 在pos位置插入string类字符串// string& insert (size_t pos, const string& str);s1.insert(0, tmp);cout << s1 << endl;// 在pos位置插入str的子串(subpos位置开始的sublen个字符)// string& insert (size_t pos, const string& str, size_t subpos, size_t sublen);s1.insert(7, tmp, 0, 6);cout << s1 << endl;// 在pos位置插入字符指针指向的字符串// string& insert (size_t pos, constchar* s);s1.insert(2, "xxx");cout << s1 << endl;// 在pos位置插入字符指针指向的字符串的前n个字符// string& insert (size_t pos, const char* s, size_t n);s1.insert(7, "hello naiths", 8);cout << s1 << endl;// 在pos位置插入n个c字符// string& insert (size_t pos, size_t n, char c);s1.insert(0, 5, 'y');cout << s1 << endl;// 指定迭代器的位置插入n个字符c// void insert (iterator p, size_t n, char c);string::iterator it = s1.begin() + 10;s1.insert(it, 10, 'z');cout << s1 << endl;// 指定迭代器的位置插入字符c// iterator insert (iterator p, char c);s1.insert(s1.begin(), 'A');cout << s1 << endl;// 指定p位置插入迭代器区间的字符// template <class InputIterator>// void insert(iterator p, InputIterator first, InputIterator last);s1.insert(s1.begin(), tmp.begin() + 3, tmp.begin() + 8);cout << s1 << endl;// 删除pos位置开始的len个字符// string& erase (size_t pos = 0, size_t len = npos);s1.erase(2, 5);cout << s1 << endl;// 删除迭代器位置的那个字符// iterator erase (iterator p);s1.erase(s1.begin());cout << s1 << endl;// 删除迭代器区间的字符// iterator erase (iterator first, iterator last);s1.erase(s1.begin() + 2, s1.begin() + 5);cout << s1 << endl;return 0;
}

//算法库algorithm
template <class T> 
void swap ( T& a, T& b )
{T c(a); a = b; b = c;
}

void swap(string& s)
{std::swap(_str, s._str);std::swap(_capacity, s._capacity);std::swap(_size, s._size);
}

 算法库提供了swap()函数,为什么string类要单独提供一个呢?

使用string类中的swap只需要拷贝一个字符指针类型的数据,而使用算法库中的swap()需要拷贝整个string()类对象,消耗大;

 c_str()返回string类中存储字符串的字符指针,cpp需要兼容c语言,因为c语言没有string类,

 设计c_str()将string类转化为常量字符串;

find() 正向查找//从string类对象的pos位置开始,查找另一个string类对象str,
//若查找到,则返回第一次匹配的第一个字符的下标,若查找不到,返回string::npos
size_t find (const string& str, size_t pos = 0) const;//从string类对象的pos位置开始,查找常量字符串s
//若查找到,则返回第一次匹配的第一个字符的下标,若查找不到,返回string::npos
size_t find (const char* s, size_t pos = 0) const;//从string类对象的pos位置开始,查找常量字符串s的前n个字符组成的子字符串
//若查找到,则返回第一次匹配的第一个字符的下标,若查找不到,返回string::npos
size_t find (const char* s, size_t pos, size_t n) const;//从string类对象的pos位置开始,查找字符c
//若查找到,则返回第一次匹配的第一个字符的下标,若查找不到,返回string::npos
size_t find (char c, size_t pos = 0) const

 

rfind()与find()用法相同,区别仅在于find()为正向查找,而rfind()函数反向查找,不再过多赘述;

从string类对象的pos位置开始,向后提取长度为len的字符串,返回从指定位置pos开始的总长度为len的string类对象;

string类非成员函数

使用cin对string类对象进行流提取时,由于cin遇到空格与换行符会停止读取,当输入带有空格的字符串时会出现读取不完整的现象,此时需要使用getline()函数,getline()函数可以获取一行字符串,即遇到换行符才会停止读取,遇到空格不会停止读取;

相关文章:

  • 首个业内DNA存储技术规范发布
  • SpringBoot中的HttpServletRequest
  • camunda 与 pycamunda学习
  • 51单片机-蜂鸣器
  • 【安全类书籍-2】Web渗透测试:使用Kali Linux
  • 深入理解Java中的TCP连接:三次握手和四次挥手
  • C++: 多态实现原理解析
  • 微信小程序项目实战遇到的问题
  • 详细分析Python模块中的雪花算法(附模板)
  • Django框架的全面指南:从入门到高级【第128篇—Django框架】
  • 24计算机考研调剂 | 温州大学
  • C# 连接neo4j数据库,包括非默认的neo4j默认库
  • 基于ssm+layui的图书管理系统
  • C语言分析基础排序算法——归并排序
  • jwt以及加密完善博客系统
  • 0基础学习移动端适配
  • canvas 高仿 Apple Watch 表盘
  • CNN 在图像分割中的简史:从 R-CNN 到 Mask R-CNN
  • PV统计优化设计
  • Redis 中的布隆过滤器
  • Spark in action on Kubernetes - Playground搭建与架构浅析
  • vue的全局变量和全局拦截请求器
  • windows下如何用phpstorm同步测试服务器
  • 如何胜任知名企业的商业数据分析师?
  • 少走弯路,给Java 1~5 年程序员的建议
  • 听说你叫Java(二)–Servlet请求
  • 项目管理碎碎念系列之一:干系人管理
  • 用Visual Studio开发以太坊智能合约
  • # Maven错误Error executing Maven
  • # Panda3d 碰撞检测系统介绍
  • #我与虚拟机的故事#连载20:周志明虚拟机第 3 版:到底值不值得买?
  • #中国IT界的第一本漂流日记 传递IT正能量# 【分享得“IT漂友”勋章】
  • (175)FPGA门控时钟技术
  • (23)Linux的软硬连接
  • (4)事件处理——(2)在页面加载的时候执行任务(Performing tasks on page load)...
  • (分布式缓存)Redis持久化
  • (图)IntelliTrace Tools 跟踪云端程序
  • (学习日记)2024.03.12:UCOSIII第十四节:时基列表
  • (转)【Hibernate总结系列】使用举例
  • (转载)深入super,看Python如何解决钻石继承难题
  • ..thread“main“ com.fasterxml.jackson.databind.JsonMappingException: Jackson version is too old 2.3.1
  • .360、.halo勒索病毒的最新威胁:如何恢复您的数据?
  • .NET(C#、VB)APP开发——Smobiler平台控件介绍:Bluetooth组件
  • .NET/C# 解压 Zip 文件时出现异常:System.IO.InvalidDataException: 找不到中央目录结尾记录。
  • .NetCore部署微服务(二)
  • @NestedConfigurationProperty 注解用法
  • [ IO.File ] FileSystemWatcher
  • [ Linux 长征路第二篇] 基本指令head,tail,date,cal,find,grep,zip,tar,bc,unname
  • [2024] 十大免费电脑数据恢复软件——轻松恢复电脑上已删除文件
  • [C#]扩展方法
  • [CF703D]Mishka and Interesting sum/[BZOJ5476]位运算
  • [PAT] 1041 Be Unique (20 分)Java
  • [POJ2728] Desert King
  • [Python设计模式] 第27章 正则表达式——解释器模式
  • [SetContextPropertiesRule]{Context} Setting property 'source'