C++_STL---string类

前言

说起string类,首先需要了解的是 - string类是什么?

std::string是类模板std::basic_string的一个元素类型为char的实例化,而basic_string则是对元素指针的封装。由于basic_string的实现对字符串操作进行了优化,所以它不能用来表示除char以外的对象串。但是使用string类也避免了和'\0'的纠缠不休,也就是说,string并不关心它所代表的字符串有无'\0'作为字符串的结束标志,相反'\0'是它的一个合法元素。

string类的接口与常规容器的接口基本相同,但在此基础上也添加了一些专门用来操作string的常规接口。在使用string类时,必须包含#include头文件以及using namespace std;另外,想要更加深入的了解string类,请点击string类的文档介绍~~

string类的常用接口

因为string类的接口特别多(106个接口函数),所以这里只介绍几个常用且重要的接口。

1.string类对象的常见构造

函数说明功能说明代码演示
string()构造空的string类对象,即空字符串string s1;
string(const char* str)用C-string来构造string类对象string s2("hello");
string(const char& str)拷贝构造函数string s3(s2);

2.string类对象的容量操作

函数名称功能说明函数原型
reserve为字符串预留空间void reserve(size_t n = 0);
resize将有效字符个数改成n个,多出的空间用char c填充

void resize(size_t n);

void resize(size_t n, char c);

clear清空有效字符void clear();

特别说明:

  • 使用reserve扩容时,只会影响capacity,并不会影响size;默认不会缩容
  • 使用resize扩容,不仅会影响capacity,也会影响size,并且会将开出的空间初始化为'\0'(不显示写char c的时候);缩容的时候只会影响size

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

函数名称功能说明函数原型
operator[]返回pos位置的字符char& operator[] (size_t pos);
begin + end

begin获取一个字符的迭代器 

end获取最后一个字符下一个位置的迭代器

iterator begin();

iterator end();

4. string类对象的修改操作

函数名称功能说明函数原型
operator+=在字符串后追加字符串str

string& operator+= (char c);

string& operator+= (const char* s);

c_str返回指向C格式字符串的指针const char* c_str() const;
find

从字符串pos位置开始往后找字符c,

返回该字符在字符串中的位置

size_t find(char c,size_t pos = 0) const;
size_t find (const char* s, size_t pos = 0) const;

特别说明:

  • 在string尾部追加字符时,s.push_back(c) / s.append(1, c) / s += 'c'三种的实现方式差不多,一般情况下string类的+=操作用的比较多,因为+=操作不仅可以连接单个字符,还可以连接字符串

5. string类非成员函数

函数名称功能说明函数原型
operator>>输入运算符重载istream& operator>> (istream& is, string& str);
operator<<输出运算符重载ostream& operator<< (ostream& os, const string& str);
getline获取一行字符串istream& getline (istream& is, string& str);

 特别说明:

  •         getline –> 获取一行数据(包括空格),cin不能获取空格,遇到空格就结束

vs和g++下string结构的说明

vs下string的结构

union _Bxty
{   // storage for small buffer or pointer to larger onevalue_type _buff[_BUF_SIZE];pointer _Ptr;char _Alias[_BUF_SIZE]; // to permit aliasing
} _Bx;

 string在vs下总共占28个字节,内部结构稍微复杂一点,先是有一个联合体,联合体用来定义string中字符串的存储空间:其实当size()的长度小于_buff的长度时,会优先存储在buff里面;当size()的长度大于_buff的长度时,才会存储在堆上新开辟的空间(扩容)里面。

这种设计也是有一定道理的,大多数情况下字符串的长度都小于16,那string对象创建好之后,内部已经有了16个字符数组的固定空间,不需要通过堆创建空间,效率高。


g++下string的结构

struct _Rep_base
{size_t       _M_size;size_t       _M_capacity;_Atomic_word _M_refcount;
}

 g++下,string是通过写时拷贝实现的,string对象总共占4个字节,内部只包含了一个指针,该指针将来指向一块堆空间,内部包含了如下字段:

  • 空间总大小
  • 字符串有效长度
  • 引用计数
  • 指向堆空间的指针,用来存储字符串

string类的模拟实现

与常用接口类似,这里只实现一些常用的

1.string类的默认成员函数

//构造函数
string(const char* str = "")     //字符串后面默认有一个\0,所以这里缺省值不需要 \0: _size(strlen(str))
{_str = new char[_size + 1];_capacity = _size;strcpy(_str, str);
}
//拷贝构造
//传统写法
string(const string& s)
{char* tmp = new char[s._capacity + 1];strcpy(tmp, s._str);_str = tmp;_size = s._size;_capacity = s._capacity;
}//现代写法
string(const string& s)
{string tmp(s._str);        //调用构造swap(tmp);                 //std::swap(tmp._str, _str);std::swap(tmp._size, _size);std::swap(tmp._capacity, _capacity);
}
//赋值重载
//传统写法
string& operator=(const string& s)
{if (this != &s)            //防止出现自己给自己赋值的情况{char* tmp = new char[s._capacity + 1];strcpy(tmp, s._str);delete[] _str;_str = tmp;_size = s._size;_capacity = s._capacity;}return *this;
}
//现代写法1
string& operator=(const string& s)
{if (this != &s){string tmp(s._str);   //调用构造swap(tmp);            //std::swap(tmp._str, _str);std::swap(tmp._size, _size);std::swap(tmp._capacity, _capacity);}return *this;
}
//现代写法2
string& operator=(string tmp)
{swap(tmp);                //调用拷贝构造return *this;
}

 2string类对象的修改相关函数

//查找一个字符串里是否有相应的字符
size_t find(char ch, size_t pos = 0)
{assert(pos < _size);for (int i = pos; i < _size; i++){if (_str[i] == ch){return i;}}return npos;
}
//查找一个字符串里是否有相应的子串
size_t find(const char* sub, size_t pos = 0)
{assert(pos < _size);char* ptr = strstr(_str + pos, sub);return ptr - _str;
}
//查找子串
string substr(size_t pos = 0, size_t len = npos)
{assert(pos < _size);if (len > _size - pos){string sub(_str + pos);        //构造一个子串return sub;}else{string sub;sub.reserve(len);              //为构造的子串开空间for (int i = 0; i < len; i++){sub += _str[pos + i];      //尾插}return sub;}
}

 3.string类非成员函数

//流提取
ostream& operator<<(ostream& os, string& str)
{for (size_t i = 0; i < str.size(); i++){os << str[i];}return os;
}
//流插入
istream& operator>>(istream& is, string& str)
{str.clear();        //清空有效数据char buff[128];     //开一个char类型的最大数组int i = 0;char ch = is.get();while (ch != ' ' && ch != '\n'){buff[i++] = ch; //读到的数据放到数组buff里if (i == 127)    {buff[i] = '\0';str += buff;//i = 0;}ch = is.get();}if (i != 0){buff[i] = '\0';str += buff;}return is;
}

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

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

相关文章

深入理解计算机系统 CSAPP 家庭作业6.45

CS:APP3e, Bryant and OHallaron 可以参考这里 void bijk(array A, array B, array C, int n, int bsize) {int i, j, k, kk, jj;double sum;int en bsize*(n/bsize);for (i 0; i < n; i)for (j 0; j < n; j)C[i][j] 0.0;for (kk 0; kk < en; kk bsize) {for (j…

QT拖放事件之八:通过全局剪切板中的接口QClipboard::mimeData()来获取MIME类型数据

1、演示效果 首先向剪切板写入数据,然后点击paste按钮进行从全局剪切板中 获取 MIME数据。。。 2、核心代码 void Widget::on_pasteBtn_clicked() {const QClipboard* clipBoard = QGuiApplication::clipboard()

前端路由中的meta、matched是什么?有哪些作用?

在前端路由中&#xff0c;尤其是在 Vue.js 这样的框架中&#xff0c;meta 和 matched 是两个常见的概念&#xff0c;它们提供了关于路由的额外信息和上下文 1. meta 一个可以附加到 Vue Router 路由定义上的自定义字段 它通常用于存储一些与路由相关的元数据或信息&#xff0…

算法07 深度优先搜索及相关问题详解

深搜与广搜是搜索算法中最常用的两种算法&#xff0c;通过深度优先搜索解决问题还会用到回溯和剪枝&#xff0c;让我们一起进入本章&#xff0c;了解深搜的基本概念和模板&#xff0c;并学会解决一些常见问题。 目录 问题导入 走迷宫问题 如何走&#xff1f; 问题建模 如何…

python ----- xml 命名空间与xpath详解

一、简介 本文章以如下xml 样例进行讲解命名空间和xpath xml_text"""<?xml version"1.0"?><actors xmlns:fictional"http://characters.example.com"xmlns"http://people.example.com"><actor><name>…

SpringBean的管理

一、bean的名字与标识符 <bean id"" class""></bean> bean的名字作用: 获取这个bean通过bean名字获取 bean名字配置方式: id: 唯一标志符, 命名规范与变量命名规范一样, 包含特殊符号name: 配置名字: 可以包含特殊符号,没有要求, 比如. 一…

基于支持向量机的垃圾邮件分类,使用SVM+flask+vue

sms-classify 基于支持向量机的垃圾邮件分类&#xff0c;使用SVMflaskvue 数据集和源码地址 数据集 SMS Spam Collection Data Set 来源于 UCI。样例被分为非垃圾邮件&#xff08;86.6%&#xff09;和垃圾邮件&#xff08;13.4%&#xff09;&#xff0c;数据格式如下&#xff…

网络爬虫中Xpath的使用方法

正则表达式虽然可以处理包含了诸如 HTML 或 XML 内容的字符串&#xff0c;但只能根据文本的 特征匹配字符串&#xff0c;而忽略字符串所包含的内容的真实格式。为了解决这个问题&#xff0c;Python 引入 XPath 以及支持 XPath 的第三方库 lxml&#xff0c;专门对 XML 或 HTML 格…

git 合并master到分支

master分支的代码领先自己的分支,git 如何把master分支代码合并到自己的分支 1.首先切换到主分支 git checkout master 2.使用git pull 把领先的主分支代码pull下来 git pull 3.切换到自己的分支 git checkout xxx(自己的分支) 4.把主分支的代码merge到自己的分支 git merge ma…

minio+tusd+uppy搭建文件上传服务

1、docker部署minio、tusd服务 1.1 新建docker-compose.yml minio API: http://ip:9100 minio控制台: http://ip:9101 tus API: http://ip:9102/files/ tus webhooh: http:172.0.0.1:3000/files/webhooh(用户鉴权API) version: 3.7services:minio:image: minio/minio:RELEAS…

亚马逊运营专词(一)

许多新入驻亚马逊的大陆卖家&#xff0c;对亚马逊的专业词汇还不太了解&#xff0c;导致在运营店铺的过程出现一些问题&#xff0c;今天就来讲解一下亚马逊常用的运营专词&#xff0c;方便新手卖家深入了解。 1. Listing&#xff1a;亚马逊listing指的是产品的详情页面&#xf…

通过BLE实现类似UART的串行通信:NUS服务 vs GATT服务

在物联网和智能设备的发展中&#xff0c;蓝牙低功耗&#xff08;Bluetooth Low Energy, BLE&#xff09;技术已经成为无线数据传输的重要手段。本文将介绍通过BLE实现类似UART的串行通信&#xff0c;并对比NUS服务和GATT服务的使用场景&#xff0c;帮助开发者更好地选择适合的技…

2024越南医药、制药机械展

2024年越南国际医药&#xff0c;制药装备及技术展览会 时间&#xff1a; 2024年11月21--23日 地点&#xff1a;越南胡志明市-西贡会展中心SECC 2024年越南国际医药&#xff0c;制药装备及技术展览会将于2024年11月21-23日在越南胡志明市盛大举行&#xff01;展览会以国际化、专…

【Feature Pyramid Networks for Object Detection】

Feature Pyramid Networks for Object Detection 摘要引言2 相关工作3 FPN4 应用摘要 特征金字塔是识别系统中用于检测不同尺度对象的基本组件。但是,最近的深度学习对象检测器已经避免了金字塔表示,部分原因是它们在计算和内存方面都很密集。在这篇论文中,我们利用深度卷积…

LeetCode经典题之876、143 题解及延伸

系列目录 88.合并两个有序数组 52.螺旋数组 567.字符串的排列 643.子数组最大平均数 150.逆波兰表达式 61.旋转链表 160.相交链表 83.删除排序链表中的重复元素 389.找不同 1491.去掉最低工资和最高工资后的工资平均值 896.单调序列 206.反转链表 92.反转链表II 141.环形链表 …

paddleocr查看标注好的数据错误信息

字符计数 import os import json from collections import Counter# 按字符计数 label_dir"/Users/thy/Downloads/chinese20240613" zi_ls[] with open(os.path.join(label_dir,"Label.txt")) as f:linesf.readlines()for line in lines:line line.strip…

Java面试题:聚簇索引和非聚簇索引

聚簇索引和非聚簇索引 聚簇索引(聚集索引) 将数据的存储和索引放在一块,索引结构的叶子节点保存了行数据 索引字段必须存在,且只能存在一个 非聚集索引(二级索引) 将数据和索引分开存储,索引结构的叶子节点关联的是对应的主键 索引字段可以存在多个 索引的选取规则 如果…

【学习】常用的分类网络

1. LeNet 提出时间&#xff1a;1998年最新版本&#xff1a;原始版本使用的数据集格式&#xff1a;MNIST&#xff08;28x28灰度图像&#xff09;优点&#xff1a; 结构简单&#xff0c;易于理解和实现。对于小规模图像数据集&#xff08;如MNIST&#xff09;有很好的表现。缺点…

豆瓣高分项目管理书籍推荐

&#x1f4ec;豆瓣网站上有很多项目管理领域的书籍获得了较高的评分&#xff0c;以下是一些高分项目管理书籍的精选列表&#xff0c;发出来跟大家分享一下&#xff1a; 《项目管理知识体系指南&#xff08;PMBOK指南&#xff09;》 【内容简介】这本书是美国项目管理协会&…

opencv检测图片上七种颜色,分辨颜色和对应位置

opencv检测图片上七种颜色&#xff0c;分辨颜色和对应位置 读取图片&#xff1a;使用cv2.imread()函数读取目标图片。 转换颜色空间&#xff1a;通常在HSV颜色空间中进行颜色检测&#xff0c;因为HSV颜色空间更适合描述颜色的属性。 定义颜色范围&#xff1a;为七种颜色定义…