【C++】string进一步介绍

个人主页 : zxctscl
如有转载请先通知

文章目录

  • 1. 前言
  • 2. 迭代器
    • 2.1 反向迭代器
    • 2.2 const对象迭代器
  • 3. Capacity
    • 3.1 size和length
    • 3.2 max_size
    • 3.3 capacity
    • 3.4 clear
    • 3.5 shrink_to_fit (了解即可)
    • 3.6 reserve
    • 3.7 resize
  • 4. Element access
    • 4.1 operator[]
    • 4.2 at
  • 5. Modifiers
    • 5.1 push_back
    • 5.2 append
    • 5.3 operator+=
    • 5.4 assign(了解即可)
    • 5.5 insert
    • 5.6 erase
    • 5.7 replace
    • 5.8 swap
  • 6. String operations
    • 6.1 c_str
    • 6.2 find 和 substr
    • 6.3 rfind
    • 6.4 compare
  • 7. Non-member function overloads
    • 7.1 operator+
    • 7.2 getline

1. 前言

在之前的博客中初步介绍了string一下: 【C++】string类初步介绍,那么这次来看看它的实现。

2. 迭代器

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

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

2.1 反向迭代器

在前面的一篇中已经提到了前面三个,这次来看看反向迭代器。
reverse_iterator:将给的字符串反向逆置。
在这里插入图片描述

void test_string3()
{string s1("hello,world");string::reverse_iterator rit = s1.rbegin();while (rit != s1.rend()){cout << *rit <<" ";rit++;}cout << endl;}

在这里插入图片描述
rbegin给rit,rit!=rend,然后加加rit。它本身就是反过来的,所以得用加加。
在这里插入图片描述
在这里插入图片描述

2.2 const对象迭代器

在这里插入图片描述
这里还有const对象的迭代器,他们两个有什么区别呢?
const要用const迭代器(const_iterator),不能修改对象值。

在这里插入图片描述

**iterator是可读可写,const_iterator只读。**会根据自己属性去调用。

string::iterator it2 = s1.begin();while (it2 != s1.end()){*it2 += 3;cout << *it2 << " ";it2++;}cout << endl;const string s3("hello world");string::const_iterator it3 = s3.begin();while (it3 != s3.end()){cout << *it3 << " ";it3++;}cout << endl;

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

rbegin同样有两种。
在这里插入图片描述
在这里插入图片描述
总共有四种迭代器:正向反向iterator,和正向反向const_iterator。用到最多是正向iterator。

3. Capacity

在这里插入图片描述

3.1 size和length

这里的size和length有什么区别呢?
直接用代码来测试一下:

void test_string4()
{string s1("hello world");cout << s1.size() << endl;cout << s1.length() << endl;
}

在这里插入图片描述
很显然,它们没有区别。有两个的原因是:string产生得比较早,没有出数据结构规范,在字符串长度取名字时候取的是length,后来stl出来之后,就增加了一个size。length是一个局限的取名,用size更统一。C++是两种都是兼容的。

3.2 max_size

在x86环境下来看看max_size有多大:

在这里插入图片描述
但是不同平台的max_size可能有所不同。

3.3 capacity

在这里插入图片描述

来看看capacity大小:
发现会比size要大
在这里插入图片描述
在这里插入图片描述
来看看string的扩容机制:
先取string当前的capacity,然后push_back,如果空间不够可能会引起capacity的变换;每次插入前获取新的capacity和旧的相比较看看相不相等,如果不相等,就把新的capacity赋值给旧的,并输出新的capacity。

    string s;size_t sz = s.capacity();cout << "making s grow:\n";cout << sz << endl;for (int i = 0; i < 100; ++i){s.push_back('c');if (sz != s.capacity()){sz = s.capacity();cout << "capacity changed: " << sz << '\n';}}

第一次扩容的是原基础的2倍,剩下的都是1.5倍
在这里插入图片描述
在这里插入图片描述

与linux的扩容机制是不同的。
来看看linux的扩容机制:
在这里插入图片描述
g++扩容是两倍扩:
在这里插入图片描述
STL是一个规范,规定功能,没有规定实现细节。

3.4 clear

在这里插入图片描述

clear是指的清数据,空间不一定清理:

string s1("hello world");cout << s1.size() << endl;cout << s1.length() << endl;cout << s1.capacity() << endl;cout << s1 << endl;cout << s1.capacity() << endl;s1.clear();cout << s1 << endl;cout << s1.capacity() << endl;

capacity并没有改变。
在这里插入图片描述

就算将s1多输入字符,它的的capacity在clear后也不会改变;
在这里插入图片描述

3.5 shrink_to_fit (了解即可)

如果想要缩容用就要用shrink_to_fit :
在这里插入图片描述

string s1("hello worldxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");cout << s1.size() << endl;cout << s1.length() << endl;cout << s1.capacity() << endl;cout << s1 << endl;cout << s1.capacity() << endl;cout << s1.size() << endl;s1.clear();cout << s1 << endl;cout << s1.capacity() << endl;cout << s1.size() << endl;s1.shrink_to_fit();cout << s1 << endl;cout << s1.capacity() << endl;cout << s1.size() << endl;

这里缩容到15
在这里插入图片描述

3.6 reserve

注意区分:
reserve是保留
reverse是反转,翻转

reserve是用来扩容的。
在这里插入图片描述

string s;s.reserve(100);size_t sz = s.capacity();cout << "making s grow:\n";cout << sz << endl;for (int i = 0; i < 100; ++i){s.push_back('c');if (sz != s.capacity()){sz = s.capacity();cout << "capacity changed: " << sz << '\n';}}

在这里插入图片描述
在linux里面:
在这里插入图片描述
在这里插入图片描述
reserve会不会缩容呢?
来看看代码:

string s1("hello worldxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");cout << s1.size() << endl;cout << s1.capacity() << endl;s1.reserve(20);cout << s1.size() << endl;cout << s1.capacity() << endl;

reserve是不会缩容的。
reserve比capacity大才扩容。
在这里插入图片描述

3.7 resize

resize改变size。
在这里插入图片描述

resize有三种情况。

resize从三个角度来对它进行分析:
假设这里size是17,capacity是32
在这里插入图片描述

  1. resize给的比size小,会删除
string s2("hello worldxxxx");cout << s2.size() << endl;cout << s2.capacity() << endl;s2.resize(10);cout << s2.size() << endl;cout << s2.capacity() << endl;

在这里插入图片描述

  1. resize给的在size和capacity之间,插入
   string s2("hello worldxxxx");cout << s2.size() << endl;cout << s2.capacity() << endl << endl;/*s2.resize(10);*/s2.resize(20);cout << s2.size() << endl;cout << s2.capacity() << endl;

默认插入\0
在这里插入图片描述

  1. resize给的比capacity大,扩容+插入

在这里插入图片描述

在这里插入图片描述
总之:
在这里插入图片描述
所以知道要插入多少数据,就提前开好空间,避免了扩容,提高了效率。

4. Element access

在这里插入图片描述

4.1 operator[]

在上一篇博客中已经提过了,有需要可以看看【C++】string类初步介绍
在这里插入图片描述
在用[]越界是断言错误:在这里插入图片描述

4.2 at

在这里插入图片描述

    string s1("hello world");cout << s1[6] << endl;cout << s1.at(6)<< endl;

在这里插入图片描述
at与[]的越界报错不一样
用at越界时候报的是非法在这里插入图片描述

5. Modifiers

5.1 push_back

尾插一个字符
在这里插入图片描述
想尾插一个字符:

void test_string7()
{string s1("hello world");s1.push_back('!');cout << s1 << endl;
}

在这里插入图片描述

5.2 append

append尾插,可以插入一个字符,也可以插入字符串。
在这里插入图片描述

    string s1("hello world");/*s1.push_back('!');*/s1.append("!");cout << s1 << endl;s1.append("abcd");cout << s1 << endl;

在这里插入图片描述

在这里插入图片描述
一般用得最多的就是:
在这里插入图片描述

5.3 operator+=

+=用起来就比较方便

来看个例子:

   string s1("hello world");s1 += ' ';s1 += "abc";cout << s1 << endl;

在这里插入图片描述

5.4 assign(了解即可)

assign赋值,字符覆盖在这里插入图片描述

可以把当前字符覆盖:

	string s1("hello world");cout << s1 << endl;s1.assign("xxxxx");cout << s1 << endl;

在这里插入图片描述

5.5 insert

insert都是在当前位置的前面插入
在这里插入图片描述
常用的就是:
在这里插入图片描述
举个例子:

string s1("hello world");cout << s1 << endl;s1.insert(0, "abc");cout << s1 << endl;

在这里插入图片描述

5.6 erase

erase删除
在这里插入图片描述
常用:
在这里插入图片描述
如果这个内容太短小于npos,就全部删除。

举个例子:

string s1("hello world");cout << s1 << endl;/*s1.insert(0, "abc");*/s1.erase(5,10);cout << s1 << endl;

在这里插入图片描述
erase不给值就直接删空了:
在这里插入图片描述

5.7 replace

replace替换
在这里插入图片描述

把pos位置,一个字符替换成两个xx:

    string s2("hello world");cout << s2 << endl;s2.replace(6, 1, "xx");cout << s2 << endl;

在这里插入图片描述

一般结合find()使用:
在这里插入图片描述

在这里插入图片描述
来看个代码:

string s2("hello world hello abcd");size_t pos = s2.find(' ');while (pos != string::npos){s2.replace(pos, 1, "%20");pos = s2.find(' ');}cout << s2 << endl;

在这里插入图片描述
insert erase replace要少用,因为基本上都要挪动数据,效率不高。

像替换这里还可以用范围for:

string s3;for (auto ch : s2){if (ch != ' '){s3 += ch;}else{s3 += "%20";}}cout << s3 << endl;

在这里插入图片描述

5.8 swap

在这里插入图片描述
来看一个例子:把空格位置换成20%:

void test_string9()
{string s2("hello world hello abcd");string s3;s3.reserve(s2.size());for (auto ch : s2){if (ch != ' '){s3 += ch;}else{s3 += "20%";}}cout << s3 << endl;s2.swap(s3);cout << s2 << endl;
}

在这里插入图片描述

6. String operations

在这里插入图片描述

6.1 c_str

在C语言中有打开文件的操作,在c++里面要打开文件就要用到c_str,让它来兼容C语言。
在这里插入图片描述
来个例子:

void test_string10()
{string s1("hello world");string filename("test.cpp");FILE* fout = fopen(filename.c_str(), "r");}

6.2 find 和 substr

find查找
在这里插入图片描述

substr去一个字符串的字串。

在这里插入图片描述
如果想要拿到一个文件的后缀,就用find,但要将后缀拷贝下来就得用到substr。
来看看简单的实现:

void test_string10()
{string s1("file.cpp");size_t pos1= s1.find('.');if (pos1 != string::npos){string suffix = s1.substr(pos1);cout << suffix << endl;}else{cout << "没有后缀" << endl;}
}

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

6.3 rfind

如果查最后一个序列怎么办呢?
用rfind,从后往前找
在这里插入图片描述

void test_string10()
{string s1("file.cpp.tar.zip");size_t pos1= s1.rfind('.');if (pos1 != string::npos){string suffix = s1.substr(pos1);cout << suffix << endl;}else{cout << "没有后缀" << endl;}
}

在这里插入图片描述
在这里插入图片描述
如果给的网站很多怎么按协议,域名,网址分开呢?
在这里插入图片描述
协议到:,域名从i+3的位置开始,到第一个/就结束。网址就是剩下的部分

void test_string10()
{string url1("https://legacy.cplusplus.com/reference/string/string/substr/");string protocol, domain, uri;//协议,域名,网址size_t i1 = url1.find(':');if (i1 != string::npos){protocol = url1.substr(0, i1 - 0);cout << protocol << endl;}size_t i2 = url1.find('/',i1+3);if (i2 != string::npos){domain = url1.substr(i1+3, i2-(i1+3));cout << domain << endl;uri = url1.substr(i2+1);cout << uri << endl;}
}

在这里插入图片描述

6.4 compare

compare是按照ascii比较
在这里插入图片描述

    string str1("green apple");string str2("red apple");cout << (str1 < str2) << endl;

r的ASCII比g的ASCII小:
在这里插入图片描述

7. Non-member function overloads

在这里插入图片描述

7.1 operator+

在这里插入图片描述
来用代码实现一下:

    string ss1 = "xxx";string ss2 = "yyy";string ret = ss1 + ss2;cout << ret << endl;

在这里插入图片描述

还支持这样的写法:

   string ret1 = ss1 + "yyy";string ret2 =  "yyy"+ss2;cout << ret1 << endl;cout << ret2 << endl;

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

7.2 getline

getline获取一行。
在这里插入图片描述
举个例子:获得一个字符串里面最后一个单词的长度

#include<iostream>
#include<string>
using namespace std;
int main()
{string line;// 不要使用cin>>line,因为会它遇到空格就结束了// while(cin>>line)while (getline(cin, line)){size_t pos = line.rfind(' ');cout << line.size() - pos - 1 << endl;}return 0;
}

有问题请指出,大家一起进步!!!

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

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

相关文章

Java面向对象案例之描述专业和学生(4)

类的方法图 学生类&#xff1a; 属性&#xff1a;学号&#xff0c;姓名&#xff0c;年龄&#xff0c;所学习的专业方法&#xff1a;学习的方法&#xff0c;描述学习状态。描述内容包括姓名、学号、年龄、所学习的专业信息 专业类&#xff1a; 属性&#xff1a;专业编号&#xf…

Vue 3中的reactive:响应式状态的全面管理

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

【计算机视觉】二、图像形成——实验:2D变换编辑(Pygame)

文章目录 一、向量和矩阵的基本运算二、几何基元和变换1、几何基元(Geometric Primitives)2、几何变换(Geometric Transformations)2D变换编辑器0. 程序简介环境说明程序流程 1. 各种变换平移变换旋转变换等比缩放变换缩放变换镜像变换剪切变换 2. 按钮按钮类创建按钮 3. Pygam…

基于PHP的数字化档案管理系统

有需要请加文章底部Q哦 可远程调试 基于PHP的数字化档案管理系统 一 介绍 此数字化档案管理系统基于原生PHP&#xff0c;MVC架构开发&#xff0c;数据库mysql&#xff0c;前端bootstrap。系统角色分为用户和管理员。 技术栈 php(mvc)mysqlbootstrapphpstudyvscode 二 功能 …

SwiftUI的Alert使用方式

SwiftUI的Alert使用方式 记录一下SwiftUI的Alert使用方式&#xff0c;比较简单直接上代码 import SwiftUIstruct AlertBootCamp: View {State var showAlert falsevar body: some View {Button {showAlert.toggle()} label: {Text("alert show")}/// 单按钮 // …

python知识点总结(一)

这里写目录标题 一、什么是WSGI,uwsgi,uWSGI1、WSGI2、uWSGI3、uwsgi 二、python中为什么没有函数重载&#xff1f;三、Python中如何跨模块共享全局变量?四、内存泄露是什么?如何避免?五、谈谈lambda函数作用?六、写一个函数实现字符串反转&#xff0c;尽可能写出你知道的所…

面试官:volatile如何保证可见性的,具体如何实现?

写在开头 在之前的几篇博文中&#xff0c;我们都提到了 volatile 关键字&#xff0c;这个单词中文释义为&#xff1a;不稳定的&#xff0c;易挥发的&#xff0c;在Java中代表变量修饰符&#xff0c;用来修饰会被不同线程访问和修改的变量&#xff0c;对于方法&#xff0c;代码…

电脑自带dll修复在哪里打开呢?马上教会你

由于各种原因&#xff0c;电脑可能会出现一些问题&#xff0c;其中之一就是dll文件丢失。Dll文件是动态链接库文件&#xff0c;它们包含了许多程序运行所需的函数和资源。当这些文件丢失或损坏时&#xff0c;可能会导致程序无法正常运行或出现错误提示。本文将介绍电脑dll文件丢…

Fork - 将 GitHub 的某个特定仓库复制到自己的账户下

Fork - 将 GitHub 的某个特定仓库复制到自己的账户下 1. ForeverStrongCheng/OpenCV-tutorials2. Fork -> ForeverStrongCheng/R2CNN_Faster-RCNN_TensorflowReferences 访问仓库页面&#xff0c;点击 Fork 按钮创建自己的仓库。 Fork 是将 GitHub 的某个特定仓库复制到自己…

C语言内存函数详解

文章目录 前言一、memcpy函数&#xff08;内存拷贝函数&#xff09;二、memmove重叠拷贝函数三.memset内存设置函数四.memcmp内存比较函数总结 前言 我们之前按学习了C语言标准库中提供了一系列的字符和字符串库函数&#xff0c;接下来我们就学习一下关于内存相关的一些函数。…

LeetCode 面试经典150题 26.删除有序数组中的重复项

题目&#xff1a; 给你一个 非严格递增排列 的数组 nums &#xff0c;请你 原地 删除重复出现的元素&#xff0c;使每个元素 只出现一次 &#xff0c;返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。 考虑 nums 的唯一元素的数量…

AVCE - AV Evasion Craft Online 更新 8 种加载方式 - 过 WD 等

免责声明&#xff1a;本工具仅供安全研究和教学目的使用&#xff0c;用户须自行承担因使用该工具而引起的一切法律及相关责任。作者概不对任何法律责任承担责任&#xff0c;且保留随时中止、修改或终止本工具的权利。使用者应当遵循当地法律法规&#xff0c;并理解并同意本声明…

【Linux-网络编程】

Linux-网络编程 ■ 网络结构■ C/S结构■ B/S结构 ■ 网络模型■ OSI七层模型■ TCP/IP四层模型 ■ TCP■ TCP通信流程■ TCP三次握手■ TCP四次挥手 ■ 套接字&#xff1a;socket 主机IP 主机上的进程&#xff08;端口号&#xff09;■ TCP传输文件 ■ 网络结构 ■ C/S结构…

基于java+springboot开发的计算机毕业设计网文论坛管理系统设计与实现【附源码】

基于javaspringboot开发的计算机毕业设计网文论坛管理系统设计与实现【附源码】 &#x1f345; 作者主页 央顺技术团队 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 文末获取源码联系方式 &#x1f4dd; &#x1f345; 查看下方微信号获取联…

JavaScript 基础知识

一、初识 JavaScript 1、JS 初体验 JS 有3种书写位置&#xff0c;分别为行内、内部和外部。 示例&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"wid…

深入了解 大语言模型(LLM)微调方法

引言 众所周知&#xff0c;大语言模型(LLM)正在飞速发展&#xff0c;各行业都有了自己的大模型。其中&#xff0c;大模型微调技术在此过程中起到了非常关键的作用&#xff0c;它提升了模型的生成效率和适应性&#xff0c;使其能够在多样化的应用场景中发挥更大的价值。 那么&…

pta上的几个例题

c语言中的小小白-CSDN博客c语言中的小小白关注算法,c,c语言,贪心算法,链表,mysql,动态规划,后端,线性回归,数据结构,排序算法领域.https://blog.csdn.net/bhbcdxb123?spm1001.2014.3001.5343 给大家分享一句我很喜欢我话&#xff1a; 知不足而奋进&#xff0c;望远山而前行&am…

Git学习记录

目录 Git Git介绍 版本控制 版本控制工具 集中式版本控制工具 分布式版本控制工具 Git工作机制 ​编辑 Git和代码托管中心 Git安装 Git常用命令 设置用户签名 初始化本地库 查看本地库状态 添加到暂存区 提交到本地库 修改文件 历史版本 查看历史版本 版本…

【系统架构师】-第3章-信息系统基础知识

1、信息系统的基本功能 输入&#xff1a;决定于系统所要达到的目的及系统的能力和信息环境的许可存储&#xff1a;存储各种信息资料和数据的能力处理&#xff1a;数据处理工具&#xff0c;利用OLAP、DM&#xff08;数据挖掘&#xff09;技术输出&#xff1a;保证最终实现最佳的…

SQLiteC/C++接口详细介绍之sqlite3类(八)

返回目录&#xff1a;SQLite—免费开源数据库系列文章目录 上一篇&#xff1a;SQLiteC/C接口详细介绍之sqlite3类&#xff08;七&#xff09; 下一篇&#xff1a; SQLiteC/C接口详细介绍之sqlite3类&#xff08;八&#xff09;&#xff08;暂未发表&#xff09; 24.sqlite3_cr…