C++相关概念和易错语法(11)(npos、string的基本使用)

本文主要是分享一些基础的用法和接口,不会涉及迭代器版本,也没有底层概念,主要是保证简单入门和使用。

1.npos

string本质上是一个类,里面包含了上百个成员函数,在调用这个头文件后,我们要知道整个类都被包含在了std这个命名空间域里,因此我们要注意在大型项目中不适用using namespace std的地方时如何使用这个类。

在string里npos使用非常常见,npos是static const size_t npos = -1(大约42亿),在很多函数的参数部分作为缺省值补充

注意,这只适用于x86平台,在x64里,这个数会大很多,经过计算相当于long int的无符号最大数,占了8个字节

2.string的增删查改操作

string帮我们实现了很多的东西,让我们可以更方便地解决一些问题,将精力放在项目更关键的地方,而不是像C语言一样每个细枝末节都要去手动实现。并且,string是一个将数据和方法封装到一起的类,体现了OOP(面向对象编程)特性,而C语言中的字符串函数相比来说是数据方法分离的,并没有这一思想。

string的功能主要分为增删查改。但由于string的设计相对来说很复杂(string设计在STL之前,时间太早不太成熟,设计出现了很多冗余的接口),平时使用的时候就主要使用关键的几个,保证功能的实现即可,所以这篇文章会分享一些基础的有用的接口。

(1)增

①初始化(构造函数)

但是我们要注意的是这里面有很多的构造函数,在使用的时候是去找最匹配的。我们有时候使用的构造函数带有缺省值npos,但有的有没有,这就导致了有些函数容易造成我们理解上的歧义,需要我们着重理解。

通过分析我们发现当数据存在类型转换的时候,会去匹配最合适的函数,特别是针对字符串->类的隐式类型转换,有时候少一个参数会影响前面参数的解读,导致代码的意思完全不一样。

除此之外,我们知道有的函数进行了特殊处理,导致我们在写参数的时候可以随便写大,但有的函数就会导致越界访问,需要我们注意。

size_t len和size_t n在这里意思其实都是一样的,即从输入的str(s)中往后选取len(n)个字符构成的串初始化对象。但是区别在于len读到\0就会强制停止,而n读到\0不会停下来,会出现越界

在后面的函数中,只要是参数格式和这个相同的都会出现这种情况,需要我们多注意,否则会不经意写出很多bug。我们也可以通过其它办法进一步探究这两个函数对参数处理的区别

可以看到,在string (const char* s, size_t n);里会忽略\0的阻拦强制向后读,而string (const string& str, size_t pos, size_t len = npos);最多读到\0结束

②push_back

参数:void push_back (char c);

push_back是在已有字符串后面加上新的单字符,注意只能加一个字符,字符串不行

③append和+=

append就是追加,在参数方面和构造函数几乎一模一样

下面是用法的实例,可以稍微分析一下保证掌握:

但是,这种用法除了不方便、有时会导致歧义以外,还存在一个易错点,下面来看看这个结果:

在这种情况下,由于数据连续存储,当出现了越界访问时,会导致如上面这样的数据污染,而这样的代码并没有报错,这就很需要我们注意在追加的时候不要像构造函数那样在size_t n这个参数上随便填,最好遵循真实情况来写,我们无法保证编译器帮我们解决了这个问题。

在大部分情况下,我们遇到的追加都是整段整段的,所以在追加时我们可以直接用+=来写,方便且容易理解。

但是要注意的是+=不能对+=后跟的数据进行裁切,这是+=劣于append的一点,但绝大多数情况是够用的,如果确实要用到append,注意上面我说的要根据实际来填写参数防止越界。

下面是简单的实例:

④insert

当我们需要在字符串中间插入字符或字符串时,可以考虑使用insert

下面是一些简单使用示例:

insert要慎重使用,因为插入往往意味着要挪动数据,这会出现效率不高的问题

(2)删

①erase、clear

erase可以从指定的位置pos开始向后清除len个数据

一般来说,erase已经满足了我们的需求,掌握这一个即可,clear可以在特殊场景使用

clear:参数:void clear();        清空字符串

②pop_back

参数:void pop_back();

删除最后一个字符

(3)查

①operator[]、at

operator[]:参数:char& operator[] (size_t pos);        针对string(可修改)

const char& operator[] (size_t pos) const;        针对const string(字符串不能修改)

这个用法很自然,没什么学习难度,但我们可以注意一下这个返回值char&,即字符串对应下标的对应数据的引用,意思就是我们直接拿到了原始数据的引用,这也就意味着除了查找以外,我们还可以用这个引用对原始的字符串进行修改操作(如++和--),我们发现这继承了数组的修改数据的用法。这个特性彻底地和指针、传值拉开了差距,使得它不可以替代

at:参数:char& at (size_t pos);
const char& at (size_t pos) const;

at和operator[]在用法和效果上完全一致,区别在于越界访问时operator[]直接assert,而at会抛异常

②size、lenth、max_size、empty

这四个函数是用来查数组的大小相关的信息

size、lenth:都是只访问不修改

参数:size_t size() const;

size_t length() const;

这两个函数的含义完全一致,就是计算字符串的大小,但是值得注意的是,lenth是单独为string这个容器设立的,而size适用于所有容器,因此一般情况下建议使用size

我们可以看到,size和lenth都不会计算\0

max_size:参数:size_t max_size() const;

用来查询字符串允许的最大长度,几乎没什么用,因为一般情况不会触及到这个最大值,下面是在x64下允许存储的最大长度,相当于有符号long int能存的最大值,需要8589934592G的空间,这是不可能达到的。

x86对应的就是有符号int的最大值,需要约2G的空间

empty:参数:bool empty() const;

用来判断字符串是否是空,在很多地方还是很有用处的

③find、rfind

当我们需要在字符串中找某个字符或字符串的时候,我们就可以考虑使用find、rfind

rfind和find在用法上完全一致,只不过rfind是从字符串后向前找,找到了就返回值。第二个参数的含义是从后向前找的第一个字符。

④c_str、data

参数:const char* c_str() const;

const char* data() const;

c_str、data用法效果完全一致

在使用string的过程中,如果我们需要用到一些C语言相关的函数,必须传址的时候,我们应该得到存这个串的地址,这个时候使用c_str即可

但是我们一定要注意这个函数const char* c_str() const;被const修饰,也就是我们不能外调函数来修改它的值,这体现的是C++的封装思想。

(4)改

①assign(覆盖)

当我们想要将整个字符串覆盖重写的话,我们可以考虑使用assign

使用的注意事项和上面的一样,掌握好这几种参数模板可以用于很多相似的函数

②replace

当我们需要将一段字符串替换成其它字符或字符串时考虑使用replace

值得注意的是第二个参数len,可以随便填大,因为删完了就不会删了,没有越界访问,相当于清除pos后面所有内容

3.其它操作

下面的操作并不算常用,仅作展示

(1)取子串

(2)字符串内容交换

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

unity制作app(5)--发送数据给数据库

这个之前做过,先不做照片的。下一节再做带照片的。 第一步 收集数据 1.先做一个AppModel结构体,这个结构体需要单做的。 using System; using System.Collections.Generic; using System.Linq; using System.Text; //using Assets.Model; public clas…

LangChain连接国内大模型测试|智谱ai、讯飞星火、通义千问

智谱AI 配置参考 https://python.langchain.com/v0.1/docs/integrations/chat/zhipuai/ZHIPUAI_API_KEY从https://open.bigmodel.cn/获取 from langchain_community.chat_models import ChatZhipuAI from langchain_core.messages import AIMessage, HumanMessage, SystemMes…

Lambda表达式Stream流-函数式编程入门教程

目录 函数式编程思想 Lambda 表达式 Stream流 常用的Stream中的API 创建Stream 第一种是直接使用.Stream()的方式来创建 第二种采用.of()方式创建 具体来看看每一个API是怎么用的 concat max min findFirst findAny count peek forEach forEachOrdered skip d…

oracle 9i 行头带有scn的表

oracle 9i 行头带有scn的表 conn scott/tiger drop table t1; drop table t2; create table t1(c varchar2(5)); create table t2(c varchar2(6)) ROWDEPENDENCIES; --t2表每行都有scn,会增加六个字节的开销 alter table t1 pctfree 0; alter table t2 pctfree 0; insert in…

Array.map解析

map方法会创建一个新数组。该方法会循环数组中的每个值,如果仅仅是想循环数组不需要返回值使用数组的forEach方法就可以。原数组中的每个元素都调用一次提供的函数后的返回值组成。Array.map 它接收一个函数 这个函数可以接收三个参数 数组的每个值item 这个值的索引…

2016-2021年全国范围的2.5m分辨率的建筑屋顶数据

一、论文介绍 摘要:大规模且多年的建筑屋顶面积(BRA)地图对于解决政策决策和可持续发展至关重要。此外,作为人类活动的细粒度指标,BRA可以为城市规划和能源模型提供帮助,为人类福祉带来好处。然而&#xf…

【html项目】教你制作地表最强王者辅助网站装逼神器

今天如何教你们写教你们如何写一个 仿王者荣耀修改器装逼神器 效果图 html: <body><header> <a href"//pvp.qq.com/" class"qqq" title"王者荣耀" onclick"PTTSendClick(link,logo,logo);">王者荣耀</a>&l…

信息系统架构模型_2.面向服务架构(SOA)模式

前面讲的客户机/服务器模式&#xff0c;无论多少层的C/S软件结构&#xff0c;对外来讲&#xff0c;都只是一个单结点应用&#xff08;无论它由多个不同层的“服务”相互配合来完成其功能&#xff09;&#xff0c;具体表现为一个门户网站、一个应用系统等。而多个单点应用相互通…

到东莞樟木头“中国作家第一村”来!这里大有文“樟”

樟木头&#xff0c;古称泰安&#xff0c;一直是康泰平安、物阜民丰之地。作为东莞唯一纯客家镇&#xff0c;传自中原先民的烂漫因子让这座城市崇文重礼&#xff0c;绿水青山更氤氲出古镇芳华。这个文章锦绣地&#xff0c;以其敢为人先、勇立潮头的姿态&#xff0c;成为了各种文…

Python专题:八、列表(1)

Python的内置数据类型 数据类型&#xff1a;列表 list类型 可以是字符串&#xff0c;浮点数&#xff0c;整数&#xff0c;列表 列表特性 ①集合性的数据类型 ②列表是有序的 ③列表是可更新的 访问列表元素的方式也是[索引]&#xff0c;也是从0开始的&#xff0c;不能超过…

【姿态解算与滤波算法】

姿态解算 一、主线 姿态表示方式&#xff1a;矩阵表示&#xff0c;轴角表示&#xff0c;欧拉角表示&#xff0c;四元数表示。 惯性测量单元IMU&#xff08;Inertial Measurement Unit&#xff09;&#xff1a;MPU6050芯片&#xff0c;包含陀螺仪和加速度计&#xff0c;分别测…

ROS2 工作空间

文章目录 ROS2 工作空间创建工作空间自动安装依赖编译工作空间设置环境变量参考链接 ROS2 工作空间 工作空间可以简单理解为工程目录。 ROS 系统中一个典型的工作空间结构如图所示&#xff1a; dev_ws&#xff1a; 根目录&#xff0c;里面会有四个子目录&#xff08;子空间&a…

net 7部署到Linux并开启https

1.修改代码设置后台服务运行 安装nuget包 Install-Package Microsoft.Extensions.Hosting.WindowsServices Install-Package Microsoft.Extensions.Hosting.Systemd在Program代码中设置服务后台运行 var builder WebApplication.CreateBuilder(args);if (System.OperatingS…

鸿蒙开发接口Ability框架:【DataAbilityHelper模块(JS端SDK接口)】

DataAbilityHelper模块(JS端SDK接口) 说明&#xff1a; 本模块首批接口从API version 7开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。 本模块接口仅可在FA模型下使用。 使用说明 使用前根据具体情况引入如下模块 import featureAbility from …

跳跃游戏 II解题思路详解

题解 跳跃游戏 II &#x1f91a;我的博客&#x1f95b;前言 跳跃游戏 II描述示例提示 题解初步思考思路细节代码实现完整代码 END&#x1f4a0;END&#x1f3d5;️公众号 &#x1f91a;我的博客 欢迎光临我的博客&#xff1a;https://blog.csdn.net/qq_52434217?typeblog &a…

两个系统中的数据匹配方法

一、首先介绍几种常用的相似度计算 1.1最长公共子序列(LCS) 最长公共子序列&#xff08;Longest Common Subsequence&#xff0c;简称LCS&#xff09;是在两个或多个序列中寻找最长的公共子序列的问题。这里所说的“子序列”指的是原序列中元素的子集&#xff0c;但保持元素的原…

暗区突围资格 暗区突围测试资格 暗区突围资格申请

《暗区突围》作为一款备受瞩目的战术射击手游&#xff0c;以其独特的撤离玩法、高度拟真的枪战体验以及丰富的装备搜集系统&#xff0c;在玩家群体中迅速积累了极高的人气。游戏设定在一个充满未知与危险的封闭区域&#xff0c;玩家需要凭借智慧、策略与精湛的操作&#xff0c;…

使用./build.sh编译ORB_SLAM源码时出现报错:/usr/bin/ld:找不到 -lboost_serialization的解决办法

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、/usr/bin/ld:找不到 -lboost_serialization1.问题描述2.解决(1). 下载源码(2) . 编译安装 一、/usr/bin/ld:找不到 -lboost_serialization 1.问题描述 在安装…

DPDK e1000 ring buffer

基本原理 如图&#xff08;盗图&#xff09; 内存&#xff08;RAM&#xff09;和网卡&#xff08;NIC&#xff09;之间通过Descriptor ring 交互网络报文数据内存中需要申请内存 packet buffer 的内存池&#xff0c;内存池中的每个实例&#xff0c;地址是物理连续的或者IOVA…

day3_prefixSum

一、前缀和技巧 重点 前缀和技巧适用于快速、频繁地计算一个索引区间内的元素之和 个人理解&#xff1b;预计算&#xff0c;空间换时间 1.(一维数组的前缀和)303区域和检索-数组不可变 获取闭区间值 [left,right] -> preSum[right 1] - preSum[left],其中preSum[right…