C++初阶(十一)--STL--string类

目录

一、string类的概述

二、string类的创建与初始化

1. 直接初始化

2. 无参初始化

3. 从字符数组初始化

三、string类的基本操作

1.string的定义方式

2.string的插入

3.string的拼接 

4.string的删除

5.string的查找

6.string的比较

7.string的大小和容量

8.string中与迭代器相关的函数

9.string中的操作符

10.string中元素的访问

11.string中的getline函数


一、string类的概述

在 C++ 中,string类是用于处理字符串的标准类。它提供了一种方便、灵活且功能强大的方式来操作字符序列,相较于传统的 C 风格字符数组,string类隐藏了许多底层的内存管理细节,让程序员能够更专注于字符串本身的处理逻辑。

二、string类的创建与初始化

1. 直接初始化

可以使用双引号括起来的字符串常量直接初始化一个string对象,就像这样:

string str1 = "Hello";

2. 无参初始化

也可以先创建一个空的string对象,然后再根据需要进行赋值等操作,例如:

string str2;
str2 = "World";

首先创建了一个空的string对象str2,之后通过赋值操作将其设置为 "World"。

3. 从字符数组初始化

如果已经有一个 C 风格的字符数组,也可以用它来初始化string对象,如下:

char charArray[] = {'H', 'e', 'l', 'l', 'o'};
string str3(charArray);

 这里通过string类的构造函数,将字符数组charArray转换为了string对象str3

三、string类的基本操作

学习这一部分,我们一定要学会看文档,虽然通过基础的学习和一些常见示例可以掌握其主要的操作方法,比如字符串拼接、查找、截取等,但它还有很多细节之处以及一些不那么常用但在特定场景下很关键的功能。文档会全面且详细地列出string类所提供的所有成员函数、它们的具体用法、参数含义以及返回值情况等。

点击:文档的网址

1.string的定义方式

string类实现了多个构造函数的重载,常用的构造函数如下:

string();  //构造一个空字符串string(const char* s);  //复制s所指的字符序列string(const char* s, size_t n);  //复制s所指字符序列的前n个字符string(size_t n, char c);  //生成n个c字符的字符串string(const string& str);  //生成str的复制品string(const string& str, size_t pos, size_t len = npos);  //复制str中从字符位置pos开始并跨越len个字符的部分

 使用示例:

string s1;                     //构造空字符串
string s2("hello string");     //复制"hello string"
string s3("hello string", 3);  //复制"hello string"的前3个字符
string s4(10, 's');            //生成10个's'字符的字符串
string s5(s2);                 //生成s2的复制品
string s6(s2, 0, 4);           //复制s2中从字符位置0开始并跨越4个字符的部分

 以上的这些在文档中都是有的。

 下面是使用方法,如果看不懂,可以借助翻译软件,但建议尽量培养独自阅读英文文档的能力。

 2.string的插入

使用push_back进行尾插

#include <iostream>
#include <string>
using namespace std;
int main()
{string s;s.push_back('C');s.push_back('S');s.push_back('D');s.push_back('N');cout << s << endl; //CSDNreturn 0;
}

使用insert插入

接下来我们只举部分的列子,详细内容可以查看文档

string& insert (size_t pos, const string& str);
string& insert (size_t pos, const string& str, size_t subpos, size_t sublen);
string& insert (size_t pos, const char* s);
iterator insert (iterator p, char c); 

 示例:

#include <iostream>
#include <string>
using namespace std;
int main()
{string s("C"); //Cstring s1("hello world");string s2("123");//insert(pos, str)在pos位置插入字符串strs.insert(1, "S"); //CS//insert (pos, str, subpos,sublen);在s1的pos位置追加s2的sublen个字符,并且从s2的subpos位置拿数据开始s1.insert(5, s2, 1, 2);//hellow3 world//insert(pos, string)在pos位置插入string对象string t("D");s.insert(2, t); //CSD//insert(pos, char)在pos位置插入字符chars.insert(s.end(), 'N'); //CSDNcout << s << endl; //CSDNcout << s1 << endl;return 0;
}

3.string的拼接 

使用append函数完成string的拼接:

代码示例: 

#include <iostream>
#include <string>
using namespace std;
int main()
{string s1("I");string s2(" like");//append(string)完成两个string对象的拼接s1.append(s2); //I like//append(str)完成string对象和字符串str的拼接s1.append(" C++"); //I like C++//append(n, char)将n个字符char拼接到string对象后面s1.append(3, '!'); //I like C++!!!cout << s1 << endl; //I like C++!!!return 0;
}

 4.string的删除

使用pop_back进行尾删

 

#include <iostream>
#include <string>
using namespace std;
int main()
{string s("C++");s.pop_back();s.pop_back();cout << s << endl; //Creturn 0;
}

 使用erase删除

#include <iostream>
#include <string>
using namespace std;
int main()
{string s("I like C++!!!");//erase(pos, n)删除pos位置开始的n个字符s.erase(8, 5); //I like C//erase(pos)删除pos位置的字符s.erase(s.end()-1); //I like//erase(pos1, pos2)删除[pos1pos2)上所有字符s.erase(s.begin() + 1, s.end()); //Icout << s << endl; //Ireturn 0;
}

5.string的查找

使用find函数正向搜索第一个匹配项

#include <iostream>
#include <string>
using namespace std;
int main()
{string s1("http://www.cplusplus.com/reference/string/string/find/");//find(string)正向搜索与string对象所匹配的第一个位置string s2("www");size_t pos1 = s1.find(s2);cout << pos1 << endl; //7//find(str)正向搜索与字符串str所匹配的第一个位置char str[] = "cplusplus.com";size_t pos2 = s1.find(str);cout << pos2 << endl;  //11//find(char)正向搜索与字符char所匹配的第一个位置size_t pos3 = s1.find(':');cout << pos3 << endl; //4return 0;
}

使用rfind函数反向搜索第一个匹配项 

#include <iostream>
#include <string>
using namespace std;
int main()
{string s1("http://www.cplusplus.com/reference/string/string/find/");//rfind(string)反向搜索与string对象所匹配的第一个位置string s2("string");size_t pos1 = s1.rfind(s2);cout << pos1 << endl; //42//rfind(str)反向搜索与字符串str所匹配的第一个位置char str[] = "reference";size_t pos2 = s1.rfind(str);cout << pos2 << endl;  //25//rfind(char)反向搜索与字符char所匹配的第一个位置size_t pos3 = s1.rfind('/');cout << pos3 << endl; //53return 0;
}

 6.string的比较

使用compare函数完成比较:

比较规则:

#include <iostream>
#include <string>
using namespace std;
int main()
{string s1("hello world");string s2("hello CSDN");//"hello world"和"hello CSDN"比较cout << s1.compare(s2) << endl; //1//"ell"和"hello CSDN"比较cout << s1.compare(1, 3, s2) << endl; //-1//"hello"和"hello"比较cout << s1.compare(0, 4, s2, 0, 4) << endl; //0return 0;
}

7.string的大小和容量

使用size函数或length函数获取当前有效字符的个数

这个比较简单,但我们很多地方要用到,只举例代码:

#include <iostream>
#include <string>
using namespace std;
int main()
{string s("CSDN");cout << s.size() << endl; //4cout << s.length() << endl; //4return 0;
}

使用max_size函数获取string对象对多可包含的字符数

#include <iostream>
#include <string>
using namespace std;
int main()
{string s("CSDN");cout << s.max_size() << endl; //4294967294return 0;
}

 使用capacity函数获取当前对象所分配的存储空间的大小

 

#include <iostream>
#include <string>
using namespace std;
int main()
{string s("CSDN");cout << s.capacity() << endl; //15return 0;
}

使用resize改变当前对象的有效字符的个数

 

#include <iostream>
#include <string>
using namespace std;
int main()
{string s1("CSDN");//resize(n)n大于对象当前的size时,将size扩大到n,扩大的字符默认为'\0's1.resize(20);cout << s1 << endl; //CSDNcout << s1.size() << endl; //20cout << s1.capacity() << endl; //31string s2("CSDN");//resize(n, char)n大于对象当前的size时,将size扩大到n,扩大的字符为chars2.resize(20, 'x');cout << s2 << endl; //CSDNxxxxxxxxxxxxxxxxcout << s2.size() << endl; //20cout << s2.capacity() << endl; //31string s3("CSDN");//resize(n)n小于对象当前的size时,将size缩小到ns3.resize(2);cout << s3 << endl; //CScout << s3.size() << endl; //2cout << s3.capacity() << endl; //15return 0;
}

注意:若给出的n大于对象当前的capacity,则capacity也会根据自己的增长规则进行扩大。 

 使用reserve改变当前对象的容量大小

#include <iostream>
#include <string>
using namespace std;
int main()
{string s("CSDN");cout << s << endl; //CSDNcout << s.size() << endl; //4cout << s.capacity() << endl; //15//reverse(n)当n大于对象当前的capacity时,将当前对象的capacity扩大为n或大于ns.reserve(20); cout << s << endl; //CDSNcout << s.size() << endl; //4cout << s.capacity() << endl; //31//reverse(n)当n小于对象当前的capacity时,什么也不做s.reserve(2);cout << s << endl; //CDSNcout << s.size() << endl; //4cout << s.capacity() << endl; //31return 0;
}

注意:此函数对字符串的size没有影响,并且无法更改其内容

使用clear删除对象的内容,删除后对象变为空字符串

#include <iostream>
#include <string>
using namespace std;
int main()
{string s("CSDN");//clear()删除对象的内容,该对象将变为空字符串s.clear();cout << s << endl; //空字符串return 0;
}

 使用empty判断对象是否为空

#include <iostream>
#include <string>
using namespace std;
int main()
{string s("CSDN");cout << s.empty() << endl; //0//clear()删除对象的内容,该对象将变为空字符串s.clear();cout << s.empty() << endl; //1return 0;
}

8.string中与迭代器相关的函数

与正向迭代器相关的函数
begin函数:返回一个指向字符串第一个字符的迭代器。

 end函数:返回一个指向字符串结束字符的迭代器,即’\0’。

 

#include <iostream>
#include <string>
using namespace std;
int main()
{string s("hello string");//正向迭代器string::iterator it = s.begin();while (it != s.end()){cout << *it;it++;}cout << endl; //hello stringreturn 0;
}

 与反向迭代器相关的函数
rbegin函数:返回指向字符串最后一个字符的反向迭代器。

 rend函数:返回指向字符串第一个字符前面的理论元素的反向迭代器。

#include <iostream>
#include <string>
using namespace std;
int main()
{string s("hello string");//反向迭代器string::reverse_iterator rit = s.rbegin();while (rit != s.rend()){cout << *rit;rit++;}cout << endl; //gnirts ollehreturn 0;
}

9.string中的操作符

operator=

#include <iostream>
#include <string>
using namespace std;
int main()
{string s1;string s2("CSDN");//支持string类的赋值s1 = s2;cout << s1 << endl; //CSDN//支持字符串的赋值s1 = "hello";cout << s1 << endl;  //hello//支持字符的赋值s1 = 'x';cout << s1 << endl; //xreturn 0;
}

 operator+=

#include <iostream>
#include <string>
using namespace std;
int main()
{string s1;string s2("hello");//支持string类的复合赋值s1 += s2;cout << s1 << endl; //hello//支持字符串的复合赋值s1 += " CSDN";cout << s1 << endl; //hello CSDN//支持字符的复合赋值s1 += '!';cout << s1 << endl; //hello CSDN!return 0;
}

operator+

#include <iostream>
#include <string>
using namespace std;
int main()
{string s;string s1("super");string s2("man");char str[] = "woman";char ch = '!';//string类 + string类s = s1 + s2;cout << s << endl; //superman//string类 + 字符串s = s1 + str;cout << s << endl; //superwoman//字符串 + string类s = str + s1;cout << s << endl; //womansuper//string类 + 字符s = s1 + ch;cout << s << endl; //super!//字符 + string类s = ch + s1;cout << s << endl; //!superreturn 0;
}

operator>> 和 operator<<

string类中也对>>和<<运算符进行了重载,这就是为什么我们可以直接使用>>和<<对string类进行输入和输出的原因。

istream& operator>> (istream& is, string& str);
ostream& operator<< (ostream& os, const string& str);

 代码示例:

#include <iostream>
#include <string>
using namespace std;
int main()
{string s;cin >> s; //输入cout << s << endl; //输出return 0;
}

10.string中元素的访问

[ ]+下标
 因为string类对[ ]运算符进行了重载,所以我们可以直接使用[ ]+下标访问对象中的元素。并且该重载使用的是引用返回,所以我们可以通过[ ]+下标修改对应位置的元素。

#include <iostream>
#include <string>
using namespace std;
int main()
{string s("CSDN");//[]+下标访问对象元素for (size_t i = 0; i < s.size(); i++){cout << s[i];}cout << endl;//[]+下标修改对象元素内容for (size_t i = 0; i < s.size(); i++){s[i] = 'x';}cout << s << endl; //xxxxreturn 0;
}

 使用at访问对象中的元素
 因为at函数也是使用的引用返回,所以我们也可以通过at函数修改对应位置的元素

#include <iostream>
#include <string>
using namespace std;
int main()
{string s("CSDN");for (size_t i = 0; i < s.size(); i++){//at(pos)访问pos位置的元素cout << s.at(i);}cout << endl;for (size_t i = 0; i < s.size(); i++){//at(pos)访问pos位置的元素,并对其进行修改s.at(i) = 'x';}cout << s << endl; //xxxxreturn 0;
}

 使用范围for访问对象中的元素
 需要特别注意的是:若是需要通过范围for修改对象的元素,则用于接收元素的变量e的类型必须是引用类型,否则e只是对象元素的拷贝,对e的修改不会影响到对象的元素。

 

#include <iostream>
#include <string>
using namespace std;
int main()
{string s("CSDN");//使用范围for访问对象元素for (auto e : s){cout << e;}cout << endl; //CSDN//使用范围for访问对象元素,并对其进行修改for (auto& e : s) //需要修改对象的元素,e必须是引用类型{e = 'x';}cout << s << endl; //xxxxreturn 0;
}

使用迭代器访问对象中的元素

#include <iostream>
#include <string>
using namespace std;
int main()
{string s("CSDN");//使用迭代器访问对象元素string::iterator it1 = s.begin();while (it1 != s.end()){cout << *it1;it1++;}cout << endl; //CSDN//使用迭代器访问对象元素,并对其进行修改string::iterator it2 = s.begin();while (it2 != s.end()){*it2 += 1;it2++;}cout << s << endl; //DTEOreturn 0;
}

11.string与字符串之间的转换

c_str的使用

c_str函数返回字符串从\0结尾的字符串,但是c++中的字符串不一定以\0结尾,c++中字符串类以size为准来结尾,所以它叫:c_str,是c语言的规则。

int main()
{
string filename("test.cpp");
cout << filename << endl;
cout << filename.c_str() << endl;filename += '\0';
filename += "string.cpp";
cout << filename << endl; // string 对象size为准--test.cppstring.cpp
cout << filename.c_str() << endl; // 常量字符串对象\0---test.cpp
}

 11.string中的getline函数

我们知道,使用>>进行输入操作时,当>>读取到空格便会停止读取,基于此,我们将不能用>>将一串含有空格的字符串读入到string对象中。

#include <iostream>
#include <string>
using namespace std;
int main()
{string s;cin >> s; //输入:hello CSDNcout << s << endl; //输出:helloreturn 0;
}

这时,我们就需要用getline函数完成一串含有空格的字符串的读取操作了。

(1)用法一

istream& getline (istream& is, string& str);

getline函数将从is中提取到的字符存储到str中,直到读取到换行符’\n’为止。

#include <iostream>
#include <string>
using namespace std;
int main()
{string s;getline(cin, s); //输入:hello CSDNcout << s << endl; //输出:hello CSDNreturn 0;
}

(2)用法二:

istream& getline (istream& is, string& str, char delim);

getline函数将从is中提取到的字符存储到str中,直到读取到分隔符delim或换行符’\n’为止。

#include <iostream>
#include <string>
using namespace std;
int main()
{string s;getline(cin, s, 'D'); //输入:hello CSDNcout << s << endl; //输出:hello CSreturn 0;
}

12. string中npos的使用

 用例:把字符串中的空格换成%%

int main()
{string s1("hello world hello bit");cout << s1 << endl;size_t i = s1.find(' ');while (i != string::npos){s1.replace(i, 1, "%%");i = s1.find(' ', i+2);}cout << s1 << endl;
}

本篇博客到此结束,欢迎评论区留言~

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

C#笔记 —— 事件

事件的语法 访问修饰符 event 委托类型 事件名&#xff1b; 例&#xff1a; public event Action myEvent; 事件的使用 事件的使用跟委托基本上一模一样&#xff0c; 1.但是事件不能在类外部直接赋值&#xff0c;只能使用 或 - 添加或删除函数&#xff1b; 2.事件不能在类…

Pandas | 理性判断数据是否存在缺失值的一种方法

理性判断 一般思路进一步思考df[B].explode() 一般思路 tcc.info()上述信息info显示没有缺失值 但是真实的情况还是要根据业务实际分析tcc.isnull().sum() # 和tcc.info()作用和tcc.info() 其实是一样的 进一步思考 在此过程中&#xff0c;我们需要检验是否存在采用别的值来表…

leetcode 382.链表随机结点

1.题目要求: 2.题目代码: /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x), next(nullptr) {}* ListNode(int x, ListNode *next) : val(x)…

Java Development Kit (JDK) 详解

什么是 JDK&#xff1f; JDK 是 Java Development Kit 的缩写&#xff0c;是一组用于开发 Java 应用程序的软件开发工具和库的集合。JDK 包含了 Java 运行时环境&#xff08;JRE&#xff09;和 Java 虚拟机&#xff08;JVM&#xff09;&#xff0c;以及一系列开发工具和库。 …

【5.8】指针算法-双指针验证回文串

一、题目 给定一个字符串&#xff0c;验证它是否是回文串&#xff0c; 只考虑字母和数字字符 &#xff0c;可以忽略字母的大小写。 说明&#xff1a; 本题中&#xff0c;我们将空字符串定义为有效的回文串。 示例 1: 输入: "A man , a plan , a canal : Panama " 输…

多功能 Web 应用渗透测试系统

系统简介 本项目命名为SecurityEye&#xff0c;是一款基于 Python-Django 的多功能 Web 应用渗透测试系统&#xff0c;包含漏洞检测、目录识别、端口扫描、指纹识别、域名探测、旁站探测、信息泄露检测、网站权重探测等功能。 项目功能 本系统通过旁站探测、域名探测、、域名…

libstdc++/so.6: version ‘GLIBCXX_3.4.29‘ not found (required by

matlab使用过程中提示库文件版图过低&#xff0c;如图 1. 网上或者其他eda的工具目录里面找一个libstdc.so.6.29文件&#xff0c;里面包含了glibcxx3.4.29 2. 复制文件到/usr/lib64目录下面 3. libstdc.so.6连接到新的库文件 unlink libstdc.so.6 ln -s libstdc.so.6.0.29 l…

有序数组的平方

给你一个按 非递减顺序 排序的整数数组 nums&#xff0c;返回 每个数字的平方 组成的新数组&#xff0c;要求也按 非递减顺序 排序。 基础使用先平方&#xff0c;后排序的思想 class Solution {public int[] sortedSquares(int[] nums) {for(int i0;i<nums.length;i){nums…

flutter 专题七 Flutter面试之渲染流程

一、 简介 Flutter面试中必问的一个面试题就是渲染相关的话题。作为Google在2018年发布的一款跨平台UI框架&#xff0c;使用Dart作为其开发语言&#xff0c;底层使用Skia图形库进行视图渲染&#xff0c;渲染速度和用户体验堪比原生。 二、Flutter渲染流程 总的来说&#xff…

深入理解 TCP 的握手与挥手机制:为何握手 3 次,挥手 4 次?

在网络通信的世界里&#xff0c;TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;是一种非常重要的协议&#xff0c;它确保了数据在网络中的可靠传输。而 TCP 的连接建立&#xff08;握手&#xff09;和连接断开&#xff08;挥手&#xff09…

Python-数据爬取(爬虫)

在数据驱动的时代&#xff0c;Python以其强大的数据处理能力和丰富的库资源&#xff0c;成为数据爬取的首选语言。通过Python&#xff0c;你可以轻松地从网页中抓取所需的数据&#xff0c;无论是价格信息、新闻内容还是用户评论&#xff0c;都能一一收入囊中。使用requests库发…

基于51单片机水位监测控制报警仿真设计

基于51单片机水位监测控制报警仿真设计 1. 主要功能&#xff1a;2. 讲解视频&#xff1a;3. 仿真4. 程序代码5. 设计报告6. 设计资料内容清单&&下载链接资料下载链接&#xff1a; 基于51单片机水位监测控制报警仿真设计( proteus仿真程序设计报告讲解视频&#xff09; …

JavaFX在Linux aarch64上运行

1.适配Jdk Linux开发项目安装在麒麟系统&#xff0c;无法安装&#xff0c;经查询因cpu架构不同导致无法运行 https://www.oracle.com/sg/java/technologies/downloads/#java21 该链接可下载jdk21,Linux aarch64版本。 2.适配Javafx模块 替换jdk之后&#xff0c;JavaFX仍无…

3D区块多重渐变围栏

这里主要用到的就是threejs的shader&#xff0c;至于其他知识点&#xff0c;可以参考json生成3d区域 下面的主要代码&#xff1a; import * as THREE from three; import { OrbitControls } from three/addons/controls/OrbitControls.js import { EffectComposer } from th…

【NLP】使用 SpaCy、ollama 创建用于命名实体识别的合成数据集

命名实体识别 (NER) 是自然语言处理 (NLP) 中的一项重要任务&#xff0c;用于自动识别和分类文本中的实体&#xff0c;例如人物、位置、组织等。尽管它很重要&#xff0c;但手动注释大型数据集以进行 NER 既耗时又费钱。受本文 ( https://huggingface.co/blog/synthetic-data-s…

Git代码托管(三)可视化工具操作(1)

常见的可视化操作工具有 一、官方网页 如码云、gitlab&#xff0c;自带了常见的git操作。 以码云为例&#xff1a; 1、创建分支&#xff1a; 进入分支目录&#xff0c;点击 新建分支 按钮&#xff0c; 在弹出框中输入新分支名称&#xff0c;点击确定即可一键创建分支&…

STL学习-无序容器-unordered set和unorderde multiset

1.定义及初始化 #include <unordered set> #include <iostream> using namespace std; //输出s中的所有元素 template<typename T> void Show(const T& s) { for(auto&x:s) cout << x<<" ";cout << endl; } int main()…

鸿蒙(Harmony)实现滑块验证码

在Android和ios两端已经使用的滑块验证码框架还未适配鸿蒙版&#xff0c;于是需要自己去实现类似如下的滑块验证码&#xff1a; 那么实现这样的验证码主要涉及到几个内容&#xff1a; 1、自定义弹窗 2、base64图片转换 3、滑动组件与滑块的联动&#xff0c;以及横移距离转换…

《华为工作法》读书摘记

无论做什么事情&#xff0c;首先要明确的就是做事的目标。目标是引导行动的关键&#xff0c;也是证明行动所具备的价值的前提&#xff0c;所以目标管理成了企业与个人管理的重要组成部分。 很多时候&#xff0c;勤奋、努力并不意味着就一定能把工作做好&#xff0c;也并不意味…

三维测量与建模笔记 - 3.3 张正友标定法

上图中&#xff0c;提到了世界坐标系在张正友标定法中的设计&#xff0c;可以理解为将世界坐标系的原点放到了棋盘格左上角点的位置&#xff0c;并且棋盘格平面上所有点的Z为0&#xff0c;将Z规定为0的话&#xff0c;可以简化掉一个维度&#xff08;列向量r3&#xff09;。去掉…