C++学习——string 详解(即C++字符串详解)

以下内容源于C语言中文网的学习与整理,非原创,如有侵权请告知删除。

一、定义string变量的方法

C++增强了对字符串的支持,除了可以使用C风格的字符串,还可以使用内置的 string 类。

string是类,而不是基本数据类型。虽然平时一般叫string变量,但切确来说应该叫string对象。

使用 string 类需要包含头文件<string>,下面的例子介绍了几种定义 string 变量的方法:

#include <iostream>
#include <string>
using namespace std;int main(){string s1;string s2 = "c plus plus";string s3 = s2;string s4 (5, 's');return 0;
}

(1)变量s1只是定义而没有初始化,此时编译器会将空字符串赋给 s1,即""。

(2)变量s2在定义的同时被初始化为"c plus plus"从中可以看出,string 变量可以直接通过赋值操作符=进行赋值。

(3)变量s3在定义的时候直接用 s2 进行初始化,因此 s3 的内容也是"c plus plus"

(4)变量s4被初始化为由 5 个's'字符组成的字符串,也就是"sssss"

二、求string字符串的长度

值得注意的是,与C风格的字符串不同,string 的结尾没有结束标志'\0'

当我们需要知道字符串长度时,可以调用 string 类提供的 length() 函数。如下所示:

string s = "http://c.biancheng.net";
int len = s.length();
cout<<len<<endl;

由于 string 的末尾没有'\0'字符,所以 length() 返回的是字符串的真实长度,而不是长度 +1。此处输出结果为22

三、将string字符串转换为C风格的字符串

虽然 C++ 提供了 string 类来替代C语言中的字符串,但是在实际编程中,有时候必须要使用C风格的字符串(例如打开文件时的路径),为此,string 类为我们提供了一个转换函数 c_str(),该函数能够将 string 字符串转换为C风格的字符串,并返回该字符串的 const 指针(const char*)。

请看下面的代码:

string path = "D:\\demo.txt";
FILE *fp = fopen(path.c_str(), "rt");

为了使用C语言中的 fopen() 函数打开文件,必须将 string 字符串转换为C风格的字符串。

四、string 字符串的输入输出

string 类重载了输入输出运算符,因此可以像对待普通变量那样对待 string 变量,也就是用>>进行输入,用<<进行输出。

请看下面的代码:

#include <iostream>
#include <string>using namespace std;int main(){string s;cin>>s;  //输入字符串cout<<s<<endl;  //输出字符串return 0;
}
http://c.biancheng.net  http://vip.biancheng.net↙
http://c.biancheng.net

虽然我们输入了两个由空格隔开的网址,但是只输出了一个网址。这是因为输入运算符>>默认遇到空格就认为输入结束,所以最后输入的http://vip.biancheng.net没有被存储到变量 s。

五、访问字符串中的字符

string 字符串也可以像C风格的字符串一样按照下标来访问其中的每一个字符。string 字符串的起始下标仍是从 0 开始。请看下面的代码:

#include <iostream>
#include <string>
using namespace std;int main(){string s = "1234567890";for(int i=0,len=s.length(); i<len; i++){cout<<s[i]<<" ";}cout<<endl;s[5] = '5';cout<<s<<endl;return 0;
}

运行结果:
1 2 3 4 5 6 7 8 9 0
1234557890

本例定义了一个 string 变量 s,并赋值 "1234567890",之后用for循环遍历输出每一个字符。借助下标,除了能够访问每个字符,也可以修改每个字符,s[5] = '5';就将第6个字符修改为 '5',所以 s 最后为 "1234557890"。

六、字符串的拼接

有了 string 类,我们可以使用++=运算符来直接拼接字符串,非常方便,再也不需要使用C语言中的 strcat()、strcpy()、malloc() 等函数来拼接字符串了,再也不用担心空间不够会溢出了。

+来拼接字符串时,运算符的两边可以都是 string 字符串,也可以是一个 string 字符串和一个C风格的字符串,还可以是一个 string 字符串和一个字符数组,或者是一个 string 字符串和一个单独的字符。请看下面的例子:

#include <iostream>
#include <string>
using namespace std;int main(){string s1 = "first ";string s2 = "second ";char *s3 = "third ";char s4[] = "fourth ";char ch = '@';string s5 = s1 + s2;string s6 = s1 + s3;string s7 = s1 + s4;string s8 = s1 + ch;cout<<s5<<endl<<s6<<endl<<s7<<endl<<s8<<endl;return 0;
}

运行结果:
first second
first third
first fourth
first @

七、string 字符串的增删改查

C++ 提供的 string 类包含了若干实用的成员函数,大大方便了字符串的增加、删除、更改、查询等操作。

1、插入字符串

insert() 函数可以在 string 字符串中指定的位置插入另一个字符串,它的一种原型为:

string& insert (size_t pos, const string& str);

pos 表示要插入的位置,也就是下标;str 表示要插入的字符串,它可以是 string 字符串,也可以是C风格的字符串。

请看下面的代码:

#include <iostream>
#include <string>
using namespace std;int main(){string s1, s2, s3;s1 = s2 = "1234567890";s3 = "aaa";s1.insert(5, s3);cout<< s1 <<endl;s2.insert(5, "bbb");cout<< s2 <<endl;return 0;
}

运行结果:
12345aaa67890
12345bbb67890

insert() 函数的第一个参数有越界的可能,如果越界,则会产生运行时异常。

更多 insert() 函数的原型和用法请参考:http://www.cplusplus.com/reference/string/string/insert/

2、删除字符串

erase() 函数可以删除 string 中的一个子字符串。它的一种原型为:

string& erase (size_t pos = 0, size_t len = npos);

pos 表示要删除的子字符串的起始下标,len 表示要删除子字符串的长度。如果不指明 len 的话,那么直接删除从 pos 到字符串结束处的所有字符(此时 len = str.length - pos)。

请看下面的代码:

#include <iostream>
#include <string>
using namespace std;int main(){string s1, s2, s3;s1 = s2 = s3 = "1234567890";s2.erase(5);s3.erase(5, 3);cout<< s1 <<endl;cout<< s2 <<endl;cout<< s3 <<endl;return 0;
}

运行结果:
1234567890
12345
1234590

有读者担心,在 pos 参数没有越界的情况下, len 参数也可能会导致要删除的子字符串越界。但实际上这种情况不会发生,erase() 函数会从以下两个值中取出最小的一个作为待删除子字符串的长度:len 的值、字符串长度减去 pos 的值,即待删除字符串最多只能删除到字符串结尾。

3、提取子字符串

substr() 函数用于从 string 字符串中提取子字符串,它的原型为:

string substr (size_t pos = 0, size_t len = npos) const;

pos 为要提取的子字符串的起始下标,len 为要提取的子字符串的长度。

请看下面的代码:

#include <iostream>
#include <string>
using namespace std;int main(){string s1 = "first second third";string s2;s2 = s1.substr(6, 6);cout<< s1 <<endl;cout<< s2 <<endl;return 0;
}

运行结果:
first second third
second

系统对 substr() 参数的处理和 erase() 类似:

  • 如果 pos 越界,会抛出异常;
  • 如果 len 越界,会提取从 pos 到字符串结尾处的所有字符。

 

4、字符串查找

string 类提供了几个与字符串查找有关的函数,如下所示。

(1)find() 函数

find() 函数用于在 string 字符串中查找子字符串出现的位置,它其中的两种原型为:

size_t find (const string& str, size_t pos = 0) const;
size_t find (const char* s, size_t pos = 0) const;

第一个参数为待查找的子字符串,它可以是 string 字符串,也可以是C风格的字符串。第二个参数为开始查找的位置(下标);如果不指明,则从第0个字符开始查找。

请看下面的代码:

#include <iostream>
#include <string>
using namespace std;int main(){string s1 = "first second third";string s2 = "second";int index = s1.find(s2,5);if(index < s1.length())cout<<"Found at index : "<< index <<endl;elsecout<<"Not found"<<endl;return 0;
}

运行结果:
Found at index : 6

find() 函数最终返回的是子字符串第一次出现在字符串中的起始下标。本例最终是在下标 6 处找到了 s2 字符串。如果没有查找到子字符串,那么会返回 string::npos,它是 string 类内部定义的一个静态常成员,用来表示 size_t 类型所能存储的最大值。

(2)rfind() 函数

rfind() 和 find() 很类似,同样是在字符串中查找子字符串,不同的是 find() 函数从第二个参数开始往后查找,而 rfind() 函数则最多查找到第二个参数处,如果到了第二个参数所指定的下标还没有找到子字符串,则返回 string::npos。

请看下面的例子:

#include <iostream>
#include <string>
using namespace std;int main(){string s1 = "first second third";string s2 = "second";int index = s1.rfind(s2,6);if(index < s1.length())cout<<"Found at index : "<< index <<endl;elsecout<<"Not found"<<endl;return 0;
}

运行结果:
Found at index : 6

(3)find_first_of() 函数

find_first_of() 函数用于查找子字符串和字符串共同具有的字符在字符串中首次出现的位置。请看下面的代码:

#include <iostream>
#include <string>
using namespace std;int main(){string s1 = "first second second third";string s2 = "asecond";int index = s1.find_first_of(s2);if(index < s1.length())cout<<"Found at index : "<< index <<endl;elsecout<<"Not found"<<endl;return 0;
}

运行结果:
Found at index : 3

本例中 s1 和 s2 共同具有的字符是‘s’,该字符在 s1 中首次出现的下标是3,故查找结果返回3。

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

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

相关文章

4.Python-用Python,Ajax实现MySQL数据库的新增数据

题记 用python&#xff0c;ajax实现mysql数据库的新增数据。以下是一个简单的实例和操作过程。 安装flask模块 pip install flask 安装mysql.connector模块 pip install mysql-connector-python 编写app.py文件 app.py文件如下&#xff1a; 块引用可能显示不完整&#x…

一键切换IP地址:电脑IP更改的简便方法

今天我要和大家分享一个电脑IP更改的简便方法——一键切换IP地址。如果您想要更改电脑的IP地址&#xff0c;无需繁琐的设置和复杂的步骤&#xff0c;只需使用以下简单的方法&#xff0c;即可轻松实现IP地址的切换。让我们开始吧&#xff01; 1、使用批处理脚本 批处理脚本是一…

java项目之学生综合考评管理系统()

项目简介 学生综合考评管理系统实现了以下功能&#xff1a; 管理员&#xff1a;个人中心、通知公告管理、班级管理、学生管理、教师管理&#xff0c;课程信息管理、作业布置管理、作业提交管理、留言信息管理、课程成绩管理。学生&#xff1a;个人中心、通知公告管理、教师管…

OpenCV学习笔记-环境搭建

文章目录 概述下载安装Visual Studio 2022下载安装OpenCVVisual Studio 配置配置包含路径配置库路径配置链接器配置环境变量Path路径 测试C测试Python 测试 概述 OpenCV&#xff08;Open source computer vision&#xff09;是一个跨平台的计算机视觉和机器学习开源库&#xf…

详解RocketMQ消息存储原理

本文基于RocketMQ 4.6.0进行源码分析 一. 存储概要设计 RocketMQ存储的文件主要包括CommitLog文件、ConsumeQueue文件、Index文件。RocketMQ将所有topic的消息存储在同一个文件中&#xff0c;确保消息发送时按顺序写文件&#xff0c;尽最大的能力确保消息发送的高性能与高吞吐…

旅游票务商城小程序的作用是什么

随着环境放开&#xff0c;旅游行业恢复了以往的规模&#xff0c;本地游、外地游成为众多用户选择&#xff0c;而在旅游时&#xff0c;不少人会报名旅行团前往各风景热点游玩&#xff0c;对旅游票务经营者而言&#xff0c;市场高需求的同时也面临一些难题。 对旅游票务经营商家…

四、RIP动态路由实验

拓扑图&#xff1a; 基本ip的配置已经配置好了&#xff0c;接下来对两台路由器配置rip协议&#xff0c;两台PC进行跨网段通讯 RIPv1版本只能识别ABC的大类网段&#xff0c;不能区分子网掩码&#xff0c;v2版本可以识别子网掩码 首先进入R1&#xff0c;进入rip&#xff0c;宣告…

springboot 使用RocketMQ客户端生产消费消息DEMO

创建springboot项目省略 项目依赖 注意&#xff1a;当前客户端版本是 5.1.3 &#xff0c;安装的rocketmq服务的版本要与其对应 <properties><java.version>11</java.version><rocketmq-client-java-version>5.1.3</rocketmq-client-java-version&…

Annoy vs Milvus:哪个向量数据库更适合您的AI应用?知其然知其所以然

1. Annoy vs Milvus简介 Annoy 和 Milvus 都是用于向量索引和相似度搜索的开源库&#xff0c;它们可以高效地处理大规模的向量数据。 Annoy&#xff08;Approximate Nearest Neighbors Oh Yeah&#xff09;&#xff1a; Annoy 是一种近似最近邻搜索算法&#xff0c;它通过构…

Flink中KeyBy、分区、分组的正确理解

1.Flink中的KeyBy 在Flink中&#xff0c;KeyBy作为我们常用的一个聚合类型算子&#xff0c;它可以按照相同的Key对数据进行重新分区&#xff0c;分区之后分配到对应的子任务当中去。 源码解析 keyBy 得到的结果将不再是 DataStream&#xff0c;而是会将 DataStream 转换为 Key…

同源策略和跨域问题

1.跨域问题产生的原因 浏览器的同源策略影响&#xff0c;同源策略是一种安全机制&#xff0c;它限制了一个网页中的脚本只能访问同源的资源。 跨源网络访问的三种方式&#xff1a;跨域写操作&#xff0c;跨域资源嵌入&#xff0c;跨域读操作 2.跨域问题案例 ip和域名不一致…

理解位运算,左移、右移、与、或、非

位运算是对二进制数的操作&#xff0c;包括左移、右移、&&#xff08;与&#xff09;、|&#xff08;或&#xff09;、^(异或)等操作。 左移 左移就是将当前的二进制数&#xff0c;整体向左移动N个单位&#xff0c;例如整数32的二级制表达为100000&#xff0c;将这个二进制…

微信小程序底部tabBar不显示图标

现场还原 在设置微信小程序底部tabBar导航图标时&#xff0c;无论如何操作均无法显示在界面上 解决思路 问题1 图标类型 一开始以为不支持png类型&#xff0c;但查看官方API仅提示ICON尺寸大小 打开其他项目可以正常展示&#xff0c;排除图标类型问题 iconPath string 否 …

【算法学习】-【滑动窗口】-【找到字符串中所有字母异位词】

LeetCode原题链接&#xff1a;438. 找到字符串中所有字母异位词 下面是题目描述&#xff1a; 给定两个字符串 s 和 p&#xff0c;找到 s 中所有 p 的 异位词 的子串&#xff0c;返回这些子串的起始索引。不考虑答案输出的顺序。 异位词 指由相同字母重排列形成的字符串&…

纯前端js中使用sheetjs导出excel,并且合并标题

先定义变量----用的是Vue2 &#xff0c;以下在vue的data&#xff1a;{}中定义--------------//空格占位符 headerTopTitle: [患者信息, , , , , , , , , 入出院信息, , , , , , , 病案首页中的出院主要诊断, ,出院其他诊断&#xff08;病案首页中原始信息&#xff09;, , , , ,…

一些常见的必须会的谭浩强基本代码大全也是常考的应试是没问题的

//1. 1£¡+2£¡+3£¡+...20! /* #include <stdio.h> int main() {int i;long sum=0,k=1;for(i=1;i<=20;i++){k*=i;sum+=k;}printf("%d",sum); } *///方法2 /* #include <stdio.h> int main() {int i,j;long sum=0,k;for(i…

UE4和C++ 开发-常用的宏(二)UPROPERTY(类似于Unity中C#的特性[SerializeField])

UPROPERTY的作用类似于Unity中C#的特性[SerializeField]或者Godot中的export。目的就是通过反射把属性暴露在蓝图或实例的细节面板。 属性说明符&#xff08;Property Specifiers&#xff09;

unity2022版本 实现手机虚拟操作杆

简介 在许多移动游戏中&#xff0c;虚拟操纵杆是一个重要的用户界面元素&#xff0c;用于控制角色或物体的移动。本文将介绍如何在Unity中实现虚拟操纵杆&#xff0c;提供了一段用于移动控制的代码。我们将讨论不同类型的虚拟操纵杆&#xff0c;如固定和跟随&#xff0c;以及如…

源码解析FlinkKafkaConsumer支持周期性水位线发送

背景 当flink消费kafka的消息时&#xff0c;我们经常会用到FlinkKafkaConsumer进行水位线的发送&#xff0c;本文就从源码看下FlinkKafkaConsumer.assignTimestampsAndWatermarks指定周期性水位线发送的流程 FlinkKafkaConsumer水位线发送 1.首先从Fetcher类开始&#xff0c…

进阶JAVA篇- DateTimeFormatter 类与 Period 类、Duration类的常用API(八)

目录 1.0 DateTimeFormatter 类的说明 1.1 如何创建格式化器的对象呢&#xff1f; 1.2 DateTimeFormatter 类中的 format&#xff08;LocalDateTime ldt&#xff09; 实例方法 2.0 Period 类的说明 2.1 Period 类中的 between(localDate1,localDate2) 静态方法来创建对象。 3.…