学习笔记—C++—string(一)
目录
string
为什么学习string的类
string类的常用接口
string类对象的常见构造
string类对象的访问及遍历操作
operator[]
迭代器
范围for
auto
迭代器(二)
string类对象的容量操作
size,length,max_size,capacity,clear基本用法
reserve 提前开空间,避免扩容的操作
resize
string类对象的修改操作
push_back尾插一个字符
append
operator+=
insert
erase
replace
c_str
rfind
find_first_of
find_last_not_off
substr
to_string
string类非成员函数
getline
总结
string
为什么学习string的类
● C语言中,字符串是以’\0’结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问。
● 在OJ中,有关字符串的题目基本以string类的形式出现,而且在常规工作中,为了简单、方便、快捷,基本都使用string类,很少有人去使用C库中的字符串操作函数
● string是一个管理字符数组的类
string类的常用接口
string类对象的常见构造
string::string - C++ Reference

int main()
{string s1;string s2("1111122222"); string s3("111111111111", 3); //前三个拷贝string s4(100, 'x'); //拷贝100个x初始化string s5(s2, 4, 3); //拷贝第四个字符起后三个字符string s6(s2, 4); //拷贝第四个字符后所以的字符,直到结束cout << s1 << endl;cout << s2 << endl;cout << s3 << endl;cout << s4 << endl;cout << s5 << endl;cout << s6 << endl;//s2.operator[](0) = 'x';s2[0] = 'x'; //修改第零个位置的字符为xs2[5] = 'x'; //修改第五个位置的字符为xcout << s2 << endl;//让s2里的所以字符++for (size_t i = 0; i < s2.size(); i++){s2[i]++;}cout << s2 << endl;return 0;
}
string类对象的访问及遍历操作

operator[]
结构
class string
{
public:char& operator[](size_t pos){assert(pos < _size);}
private:char* _str;size_t _size;size_t _capacity;
};
使用operator[]进行数组元素的遍历操作
int main()
{//operator[]可以访问数组的第pos位置的元素,越界就会直接报错的string s1("hello world");for (size_t i = 0; i < s1.size(); i++){cout << s1[i];//直接访问第i个位置的字符}return 0;
}
迭代器
通过迭代器进行遍历的实现操作,迭代器可以理解为像指针一样的东西。
int main()
{string s1("hello world");//string::iterator it1 = s1.begin();//用这个类型定义一个对象//我们这里的话begin访问的是h这个字符,end指向的是\0//这里将begin给到了it1it1 = s1.begin();while (it1 != s1.end())//end是最后一个数据的下一个位置{//下面的用法非常像指针,但是不是指针cout << *it1 << " ";++it1;}return 0;
}
//这个s1是一个类对象,然后我们利用这个string类里面的运算符

日常的通过下标[]访问很方便,但是这个不是通用的访问方式,这个只适合string和vector结构,不适合后面的结构,string和vector结构底层是连续的空间,才回去重载operator[]。
下标+[]不是通用的方式,但是迭代器是所有容器通用的方式。
列表的遍历
int main()
{list <int> lt;//创建一个模版对象lt//然后进行数据的插入操作lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);//列表list <int>::iterator it =lt.begin();while (it != lt.end()){cout << *it << " ";++it ;}return 0;
}
范围for
范围for进行遍历
// 范围for C++11 语法糖// 适用于容器遍历和数组遍历// 自动取容器的数据赋值给左边的对象// 自动++,自动判断结束// 原理:范围for底层是迭代器//for (char ch : s1)//auto可以代替类型for (auto ch : s1){cout << ch << " ";}cout << endl;// 修改for (auto& ch : s1){ch++;}for (auto ch : s1){cout << ch << " ";}cout << endl;for (auto e : It){cout << e << " ";}cout << endl;
String而言有三种遍历方式:下标+[],迭代器,范围for。
范围for用于容器遍历和数组遍历。
因为迭代器底层根指针相似,所以范围for也可以遍历数组。
auto
int i = 1;int y = i;//自动推导类型auto z = y; //intauto x = 1.1; //doubleauto n = &i; //int*int& r1 = i;auto r2 = r1; //intauto& r3 = r1; //int&
//list<int>::iterator it = It.begin();auto it = It.begin();while (it != It.end()){cout << *it << " ";++it;}cout << endl;
//auto语法糖// 简化代码,替代写起来长的类型std::map<std::string, std::string> dict;//std::map<std::string, std::string>::iterator dit = dict.begin();auto dit = dict.begin();
auto真正的价值是为了方便,简化代码,替换长类型,写起来长的类型。
auto当前是不能作为形参的,C++20开始支持auto作参数,auto可以支持作为返回值的,谨慎使用。
// C++20开始支持
void func1(auto x);auto func3()
{auto y = func4();return y;
}auto func2()
{auto x = func3();//...return x;
}
整理代码
#include<iostream>
#include<string>
#include<list>
#include<map>
using namespace std;//int main()
//{
// string s1("hello,word");
//
// //下标[]+
// for (size_t i = 0; i < s1.size(); i++)
// {
// s1[i]++;
// }
//
// for (size_t i = 0; i < s1.size(); i++)
// {
// cout<<s1[i]<<" ";
// }
// cout << endl;
//
// //迭代器
// string::iterator it1 = s1.begin();
// while (it1 != s1.end())
// {
// (*it1)--;
// ++it1;
// }
// cout << endl;
//
// it1 = s1.begin();
// while (it1 != s1.end())
// {
// cout << *it1 << " ";
// ++it1;
// }
// cout << endl;
//
// list<int> It;
// It.push_back(1);
// It.push_back(2);
// It.push_back(3);
// It.push_back(4);
//
// //list<int>::iterator it = It.begin();
// auto it = It.begin();
// while (it != It.end())
// {
// cout << *it << " ";
// ++it;
// }
// cout << endl;
//
//
// //auto语法糖
// // 简化代码,替代写起来长的类型
// std::map<std::string, std::string> dict;
// //std::map<std::string, std::string>::iterator dit = dict.begin();
// auto dit = dict.begin();
//
// // 范围for C++11 语法糖
// // 适用于容器遍历和数组遍历
// // 自动取容器的数据赋值给左边的对象
// // 自动++,自动判断结束
// // 原理:范围for底层是迭代器
// //for (char ch : s1)
// //auto可以代替类型
// for (auto ch : s1)
// {
// cout << ch << " ";
// }
// cout << endl;
//
// // 修改
// for (auto& ch : s1)
// {
// ch++;
// }
//
// for (auto ch : s1)
// {
// cout << ch << " ";
// }
// cout << endl;
//
// for (auto e : It)
// {
// cout << e << " ";
// }
// cout << endl;
//
// int i = 1;
// int y = i;
// //自动推导类型
// auto z = y; //int
// auto x = 1.1; //double
// auto n = &i; //int*
// int& r1 = i;
// auto r2 = r1; //int
// auto& r3 = r1; //int&
//
// int a[] = { 1,2,3,4,5,6 };
// for (size_t i = 0; i < sizeof(a)/sizeof(int); i++)
// {
// cout << a[i] << " ";
// }
// cout << endl;
//
// for (auto e : a)
// {
// cout << e << " ";
// }
// cout << endl;
//
// return 0;
//}C++20开始支持
//void func1(auto x);
//
//auto func3()
//{
// auto y = func4();
// return y;
//}
//
//auto func2()
//{
// auto x = func3();
// //...
// return x;
//}
迭代器(二)

反向迭代器

Const 无法调用迭代器

这种方法const就能使用迭代器,但不能修改

const反向迭代器

int main()
{string s1("hello world");string::reverse_iterator rit = s1.rbegin();while (rit != s1.rend()){cout << *rit << " ";++rit; }cout << endl;const string s2(s1);//string::const_iterator it1 = s2.begin();auto it1 = s2.begin();while (it1 != s2.end()){//*it1 += 1;cout << *it1 << " ";++it1;}cout << endl;//string::const_reverse_iterator rit1 = s2.rbegin();auto rit1 = s2.rbegin();while (rit1 != s2.rend()){cout << *rit1 << " ";++rit1;}cout << endl;return 0;
}
string类对象的容量操作

注意:
1. size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接
口保持一致,一般情况下基本都是用size()。
2. clear()只是将string中有效字符清空,不改变底层空间大小。
3. resize(size_t n) 与 resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不
同的是当字符个数增多时:resize(n)用0来填充多出的元素空间,resize(size_t n, char
c)用字符c来填充多出的元素空间。注意:resize在改变元素个数时,如果是将元素个数
增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间总大小不变。
4. reserve(size_t res_arg=0):为string预留空间,不改变有效元素个数,当reserve的参
数小于string的底层空间总大小时,reserver不会改变容量大小。

size,length,max_size,capacity,clear基本用法
int main()
{string s1("hello world");//size和length结果是一样的cout << s1.size() << endl;cout << s1.length() << endl;//看最大开辟空间,无意义cout << s1.max_size() << endl;//空间大小cout << s1.capacity() << endl;cout << endl << endl;//清除空间,让size变成0s1.clear();cout << s1.size() << endl;cout << s1.capacity() << endl;return 0;
}
reserve 提前开空间,避免扩容的操作
// reserve 保留 预留
// reverse 反向 翻转
int main()
{string s1;// 提前开空间,避免扩容s1.reserve(200);size_t old = s1.capacity();cout << "capacity:" << old << endl;for (size_t i = 0; i < 200; i++){s1 += 'x';if (s1.capacity() != old){cout << "capacity:" << s1.capacity() << endl;old = s1.capacity();}}string s3("11111111");string s4("111111112222222222222222222222222222222222222222222");cout << sizeof(s3) << endl;return 0;
}
resize

int main()
{string s1("11111111111111111111");cout << s1 << endl;cout << s1.size() << endl;cout << s1.capacity() << endl;//删除//<sizes1.resize(15);cout << s1 << endl;cout << s1.size() << endl;cout << s1.capacity() << endl;//插入//size< <capacity//把空间扩容到25,并把后面空间全部插入x; s1.resize(25)如果是这样,那么插入\0s1.resize(25,'x');cout << s1 << endl;cout << s1.size() << endl;cout << s1.capacity() << endl;//<capacity//扩容到40,并插入xs1.resize(40,'x');cout << s1 << endl;cout << s1.size() << endl;cout << s1.capacity() << endl;return 0;
}
string类对象的修改操作

push_back尾插一个字符
int main()
{string s1("hello world");//尾插字符s1.push_back(',');s1.push_back('x');cout << s1 << endl;return 0;
}
append
//int main()
//{
//
// //尾插字符串
// //插入字符串
// s1.append("orld");
// cout << s1 << endl;
//
// //插入十个感叹号
// s1.append(10, '!');
// cout << s1 << endl;
//
// //插入函数
// string s2("hello,wuguo");
// s1.append(s2.begin(), s2.end());
// cout << s1 << endl;
//
// //插入第六个函数之后的字母
// string s3("hello,wuguo");
// s1.append(s2.begin()+6, s2.end());
// cout << s1 << endl;
//
// return 0;
//}
operator+=
// //直接+=,唯一真神
// string s4("hello");
// s4 += ',';
// s4 += "world";
// cout << s4 << endl;
insert
//int main()
//{
// //Insert相当于插入
// string s1("hello,world");
// //后面的数据就是往后面进行挪动的
// s1.insert(5, "xxxxx");
// cout << s1 << endl;
//
// return 0;
//}
erase
相当于删除

replace
//int main()
//{
// //replace相当于替换
// string s1("hello,world");
// cout << s1 << endl;
// s1.replace(5, 1, "%%");
// cout << s1 << endl;
//
// return 0;
//}

加上find就能把空格也能替换了

find的默认位置是从0开始找的,我们给什么值就从什么位置开始找。
c_str

rfind
int main()
{string s3("test.cpp");//现在我们想将后缀取出来//那么我们后缀的特征就是前面有一个点,以点进行区分操作//那么这个时候就可以使用rfind了size_t pos = s3.rfind('.');if (pos != string::npos)//找到的话{//这个时候我们就找到位置了,那么我们就要利用substr这个从pos位置开始取子串string sub = s3.substr(pos);//从pos位置开始取;cout << sub << endl;}
}
find就是正向找,rfind就是倒着找。
find_first_of
// std::string str("Please, replace the vowels in this sentence by asterisks.");
// std::size_t found = str.find_first_of("aeiou");
// while (found != std::string::npos)
// {
// str[found] = '*';
// found = str.find_first_of("aeiou", found + 1);
// }
//
// std::cout << str << '\n';
//
// return 0;
//}

只要你这个字符串里面有我给的这个字符串里面任意一个字符的话,我们就将这个字符变成*。
find_last_not_off
int main()
{std::string str("Please, replace the vowels in this sentence by asterisks.");cout << str << endl;std::size_t found = str.find_first_not_of("aeiou");while (found != std::string::npos){str[found] = '*';found = str.find_first_not_of("aeiou", found + 1);}std::cout << str << '\n';return 0;
}
保留元音字母,其他字母全部屏蔽掉,只有aeiou留下来了。
substr
从pos位置取len个字符,然后将这几个衣服构成资格子串string
// string s3("test.cpp.zip");
// size_t pos = s3.rfind('.');
// if (pos != string::npos)
// {
// string sub = s3.substr(pos);
// cout << sub << endl;
// }
to_string
将数据转换为字符串
//int main()
//{
// string s3 = to_string(11.11);
//
// string s1, s2;
// cin >> s1 >> s2;
// cout << s1 << endl;
// cout << s2 << endl;
//
// return 0;
//}
string类非成员函数

getline
遇到#号才停止

总结
常用的:构造、迭代器、容量里面的几个。

相关文章:
学习笔记—C++—string(一)
目录 string 为什么学习string的类 string类的常用接口 string类对象的常见构造 string类对象的访问及遍历操作 operator[] 迭代器 范围for auto 迭代器(二) string类对象的容量操作 size,length,max_size,capacity,clear基本用法 reserve 提…...
OpenCV 图形API(55)颜色空间转换-----将图像从 RGB 色彩空间转换为 I420 格式函数RGB2I420()
操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 将图像从 RGB 色彩空间转换为 I420 色彩空间。 该函数将输入图像从 RGB 色彩空间转换为 I420。R、G 和 B 通道值的常规范围是 0 到 255。 输出图…...
GPLT-2025年第十届团体程序设计天梯赛总决赛题解(共计266分)
今天偶然发现天梯赛的代码还保存着,于是决定写下这篇题解,也算是复盘一下了 L1本来是打算写的稳妥点,最后在L1-6又想省时间,又忘记了insert,replace这些方法怎么用,也不想花时间写一个文件测试,…...
MySQL数据库精研之旅第十期:打造高效联合查询的实战宝典(一)
专栏:MySQL数据库成长记 个人主页:手握风云 目录 一、简介 1.1. 为什么要使用联合查询 1.2. 多表联合查询时的计算 1.3. 示例 二、内连接 2.1. 语法 2.2. 示例 三、外连接 4.1. 语法 4.2. 示例 一、简介 1.1. 为什么要使用联合查询 一次查询需…...
zkPass案例实战之合约篇
目录 一、contracts/contracts/ProofVerifier.sol 1. License 和 Solidity 版本 2. 导入依赖 3. 合约声明和默认分配器地址 4. 验证证明 5. 验证分配器签名 6. 验证验证者签名 7. 签名前缀处理 8. 签名恢复 总结 二、contracts/contracts/SampleAttestation.sol 1. …...
15.FineReport动态展示需要的列
1.首先连接自带的sqlite数据库,具体方法参考下面的链接 点击查看连接sqlite数据库 2.文件 – 新建普通报表 3.新建数据库查询 4.查询自带的销售明细表 5.把数据添加到格子中,并设置边框颜色等格式 6.查询新的数据集:column 7.点笔 8.全部添…...
Windows云主机远程连接提示“出现了内部错误”
今天有人反馈说有个服务器突然连不上了,让我看下什么问题,我根据他给的账号密码试了下发现提示“出现了内部错误”,然后就是一通排查 先是查看安全组,没发现特别的问题,因为也没有调过这块的配置 然后通过控制台登录进…...
最新扣子(Coze)案例教程:Excel数据生成统计图表,自动清洗数据+转换可视化图表+零代码,完全免费教程
大家好,我是斜杠君。 知识星球群有同学和我说每天的工作涉及很多数据表的重复操作,想学习Excel数据表通过大模型自动转数据图片的功能。 今天斜杠君就带大家一起搭建一个智能体,以一个销售行业数据为例,可以快速实现自动清洗Exc…...
如何安装Visio(win10)
首先下载下面这些文件 HomeStudent2021Retail.img officedeploymenttool_17531-20046.exe office中文语言包.exe 确保这些文件都在一个文件夹内(我已经上传这些资源,这些资源都是官网下载的) 官网资源下载教程 1.下载Office镜像࿰…...
建筑安全员 A 证与 C 证:差异决定职业方向
在建筑行业的职业发展道路上,安全员 A 证和 C 证就像两条不同的岔路,它们之间的差异,在很大程度上决定了从业者的职业方向。 从证书性质和用途来看,A 证是从业资格证书,更像是一把开启安全管理高层岗位的 “金钥匙”。…...
Java Arrays工具类解析(Java 8-17)
一、Arrays工具类概述 java.util.Arrays是Java集合框架中提供的数组操作工具类,包含各种静态方法用于操作数组(排序、搜索、比较、填充、复制等)。自Java 8到17版本,Arrays类不断增强了功能,特别是引入了并行操作和St…...
(19)VTK C++开发示例 --- 分隔文本读取器
文章目录 1. 概述2. CMake链接VTK3. main.cpp文件4. 演示效果 更多精彩内容👉内容导航 👈👉VTK开发 👈 1. 概述 本例采用坐标和法线(x y z nx ny nz)的纯文本文件,并将它们读入vtkPolyData并显示…...
Redis从入门到实战先导篇
前言:本节内容包括虚拟机VMware的安装,Linux系统的配置,FinalShell的下载与配置,Redis与其桌面客户端的安装指导,便于后续黑马Redis从入门到实战的课程学习 目录 主要内容 0.相关资源 1.VMware安装 2.Linux与CentOS安装 3.Fi…...
WebSocket是h5定义的,双向通信,节省资源,更好的及时通信
浏览器和服务器之间的通信更便利,比http的轮询等效率提高很多, WebSocket并不是权限的协议,而是利用http协议来建立连接 websocket必须由浏览器发起请求,协议是一个标准的http请求,格式如下 GET ws://example.com:3…...
uniapp中使用<cover-view>标签
文章背景: uniapp中遇到了原生组件(canvas)优先级过高覆盖vant组件 解决办法: 使用<cover-view>标签 踩坑: 我想实现的是一个vant组件库中动作面板的效果,能够从底部弹出框,让用户进行选择,我直…...
JavaScript 防抖和节流
方法一:使用lodash库的debounce方法 方法二:手写防抖函数 function debounce(fn,t){// 1.声明一个定时器变量 因为需要多次赋值 使用let声明let timer // 返回一个匿名函数return function(){if(timer){// 如果定时器存在清除之前的定时器 clearTimeout(…...
Spring Boot 启动时 `converting PropertySource ... to ...` 日志详解
Spring Boot 启动时 converting PropertySource ... to ... 日志详解 1. 日志背景 在 Spring Boot 应用启动过程中,会加载并处理多种 配置源(如 application.properties、系统环境变量、命令行参数等)。这些配置源会被封装为 PropertySource…...
分割数据集中.json格式标签转化成伪彩图图像
一、前言 图像分割任务中,分割数据集的转换和表示方式对于模型训练至关重要。目前主要有两种常见的分割结果表示方法: 1. 转化为TXT文件 这种方式通常使用一系列的点(坐标)来表示图像中每个像素的类别标签。每个点通常包含像素…...
Linux之彻底掌握防火墙-----安全管理详解
—— 小 峰 编 程 目录: 一、防火墙作用 二、防火墙分类 1、逻辑上划分:大体分为 主机防火墙 和 网络防火墙 2、物理上划分: 硬件防火墙 和 软件防火墙 三、硬件防火墙 四、软件防火墙 五、iptables 1、iptables的介绍 2、netfilter/…...
SwiftUI 常用控件简介
SwiftUI 是苹果公司推出的现代化声明式 UI 框架,用于构建 iOS、macOS、watchOS 和 tvOS 应用程序用户界面。以下是一些常用的 SwiftUI 控件: 1. 文本控件 Text: 显示一段文本。 2. 图像控件 Image: 显示图片,可以从系统图标、网络或本地资…...
HCIP-H12-821 核心知识梳理 (6)
ospf dr-priority命令默认值为1,取值范围为0~255.DHCPv6使用IPv6组播地址FF05::1:3用于中继代理和服务器之间的通信。VRF路由表里的OSPF外部路由允许被路由汇总(asbr-summary)在IS-IS网络中,直连的两台路由器不管是P2P网络类型或是Broadcast网…...
Docker 安装配置教程(配置国内源)
## 一、Windows 安装 Docker Desktop 1. 系统要求: - Windows 10 64位:专业版、企业版或教育版 - 必须开启 Hyper-V 和容器功能 - 至少 4GB 内存 2. 安装步骤: - 访问 Docker 官网下载 Docker Desktop - 双击安装程序 - 按照向导完成安装 - 重启电脑 ## 二、macOS 安装 Dock…...
初识分布式事务原理
事务是指符合ACID特性的操作就是事务,在同一个数据库中,如果要分别对表A和表B进行插入和删除操作,如果其中一个操作执行失败,可以对当前数据库进行回滚,使其回滚到执行操作前的状态,但是现有的系统架构都是…...
# 构建和训练一个简单的CBOW词嵌入模型
构建和训练一个简单的CBOW词嵌入模型 在自然语言处理(NLP)领域,词嵌入是一种将词汇映射到连续向量空间的技术,这些向量能够捕捉词汇之间的语义关系。在这篇文章中,我们将构建和训练一个简单的Continuous Bag of Words…...
Qt本地化-检测系统语言
获取系统语言,可以通过QLocale的接口 // 获取系统默认区域设置QLocale systemLocale QLocale::system();// 获取语言代码 (例如 "zh", "en", "ja" 等)QString language systemLocale.name().split(_).first(); //输出zh// 或者直接…...
Collection集合,List集合,set集合,Map集合
文章目录 集合框架认识集合集合体系结构Collection的功能常用功能三种遍历方式三种遍历方式的区别 List集合List的特点、特有功能ArrayList底层原理LinkedList底层原理LinkedList的应用场list:电影信息管理模块案例 Set集合set集合使用哈希值红黑树HashSet底层原理HashSet集合元…...
c++中iota容器和fill的区别
在C 中,std::iota 和 std::fill 都是标准库中的函数,用于对序列进行操作,它们的功能和用法如下: std::iota 功能:std::iota 函数用于将一个连续的递增序列赋值给指定范围的元素。它接受三个参数,第一个参…...
【CSS】层叠,优先级与继承(四):层叠,优先级与继承的关系
层叠,优先级与继承的关系 前文概括 【CSS】层叠,优先级与继承(一):超详细层叠知识点 【CSS】层叠、优先级与继承(二):超详细优先级知识点 【CSS】层叠,优先级与继承&am…...
jdk17的新特性
JDK 17 是 Java 的一个长期支持(LTS)版本,相较于 JDK 8 引入了许多新特性,下面从语法、性能、安全性等多个方面进行介绍: 语法层面 密封类(Sealed Classes) 简介:密封类和接口限制…...
C++如何分析和解决崩溃(crash)问题?如何查看core dump文件
在软件开发的世界中,C++作为一门高效且灵活的高级编程语言,广泛应用于系统编程、游戏开发、嵌入式系统以及高性能计算等领域。然而,正是由于其直接操作内存和资源的特性,C++程序在开发和运行过程中常常面临崩溃(crash)问题。这些崩溃不仅会中断程序的正常运行,还可能导致…...
