【C++】string类的使用

news/2024/5/20 18:30:06

目录

 string类对象的默认成员函数

 string类对象的容量操作

string中元素访问及遍历

 遍历方式1:下标+[]

遍历方式2: 迭代器

遍历方式3: 范围for

string类对象的修改操作

string类非成员函数

总结



string,也就是串或者字符数组,可以扩容,可以增删查改

接下来我们通过对Cplusplus的string的文档阅读来了解string的常见接口~

 string类对象的默认成员函数

string类对象的构造(包括拷贝构造)

其中,常见的函数和功能如下表:

函数名称功能说明
string() 构造空的string类对象,即空字符串
string(const string&str) 拷贝构造函数
string(const char* s) 用C-string来构造string类对象

void test_string()
{string s1;string s2("hello world");string s3(s2);
}

string类对象的赋值运算符重载

 string类对象的容量操作

函数名称功能说明
size返回字符串有效字符长度
length返回字符串有效字符长度
capacity返回空间总大小
empty 检测字符串释放为空串,是返回true,否则返回false
clear 清空有效字符
reserve (重要)为字符串预留空间**
resize (重要)将有效字符的个数该成n个,多出的空间用字符c填充

void test_string()
{string s1("hello world hello C++");cout << s1.size() << endl;cout << s1.capacity() << endl;cout << s1.max_size() << endl;
}

resize(影响size和capacity)

void test_string()
{string s1;//s1.resize(5, '0');s1.resize(5);s1[4] = '3';s1[3] = '4';s1[2] = '5';s1[1] = '6';s1[0] = '7';// 76543// 插入(空间不够会扩容)string s2("hello world");s2.resize(20, 'x');// 删除s2.resize(5);
}

reserve(影响capacity)

void test_string()
{string s1("111111111");cout << s1.capacity() << endl;s1.reserve(100);cout << s1.capacity() << endl;s1.reserve(20);cout << s1.capacity() << endl;
}

注意:
1. size()与length()方法底层实现原理完全相同,length的实现是C++发展的历史原因

其他容器的接口的我们都是用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不会改变容量大小


string中元素访问及遍历

函数名称功能说明
operator[] 返回pos位置的字符,const string类对象调用
begin+ endbegin获取一个字符的迭代器 + end获取最后一个字符下一个位置的迭
代器
rbegin + rendbegin获取一个字符的迭代器 + end获取最后一个字符下一个位置的迭
代器
范围forC++11支持更简洁的范围for的新遍历方式

 遍历方式1:下标+[]

void test_string()
{string s1("hello world");cout << s1.size() << endl;for (size_t i = 0; i < s1.size(); i++){//cout << s1.operator[](i) << " ";cout << s1[i] << " ";}cout << endl;
}

void test_string()
{	const string s("hello world");// 不可修改//s[0] = 'x';
}

遍历方式2: 迭代器

(正向迭代器和反向迭代器,各两种)

正向迭代器

void test_string(){string s1("hello world");//string::iterator it1 = s1.begin();auto it1 = s1.begin();while (it1 != s1.end()){cout << *it1 << " ";++it1;}cout << endl;
}
void test_string()
{  const string s1("hello world");//string::const_iterator it1 = s1.begin();auto it1 = s1.begin();while (it1 != s1.end()){// 不能修改//*it1 += 3;cout << *it1 << " ";++it1;}cout << endl;
}

反向迭代器(反过来遍历):

void test_string()
{string s2("hello world");//string::reverse_iterator it2 = s2.rbegin();auto it2 = s2.rbegin();while (it2 != s2.rend()){cout << *it2 << " ";++it2;}cout << endl;}

  void test_string()
{const string s1("hello world");//string::const_reverse_iterator cit1 = s1.rbegin();auto cit1 = s1.rbegin();while (cit1 != s1.rend()){// 不能修改//*cit1 += 3;cout << *cit1 << " ";++cit1;}cout << endl;
}

遍历方式3: 范围for

void test_string()
//底层角度,就是迭代器
{for (auto& e : s1){cout << e << " ";}cout << endl;
}

string类对象的修改操作

string中插入和查找等

函数名称功能说明
push_back在字符串后尾插字符c
append在字符串后追加一个字符串
operator+=在字符串后追加字符串str
c_str返回C格式字符串
find + npos从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置
rfind从字符串pos位置开始往前找字符c,返回该字符在字符串中的位置
substr在str中从pos位置开始,截取n个字符,然后将其返回


void test_string()
{string s1("hello world");cout << s1 << endl;s1.push_back('x');cout << s1 << endl;s1.append(" yyyyyy!!");cout << s1 << endl;string s2("111111");s1 += 'y';s1 += "zzzzzzzz";s1 += s2;cout << s1 << endl;
}

接下来看一下insert和erase

void test_string()
{string s1("hello world");cout << s1 << endl;// 慎用,因为效率不高 -> O(N)// 实践中需求也不高string s2("hello world");s2.insert(0, "xxxx");cout << s2 << endl;s2.insert(0, 1,'y');cout << s2 << endl;s2.insert(s2.begin(), 'y');cout << s2 << endl;s2.insert(s2.begin(), s1.begin(), s1.end());cout << s2 << endl;
}

void test_string()
{string s1("hello world");cout << s1 << endl;// erase效率不高,慎用,和insert类似,要挪动数据s1.erase(0, 1);cout << s1 << endl;//s1.erase(5);//不传s1.erase(5, 100);//传个很大的cout << s1 << endl;
}

下面看一下replace:

void test_string()
{
// replace效率不高,慎用,和insert类似,要挪动数据
string s2("hello world");
s2.replace(5, 1, "%20");
cout << s2 << endl;//功能实现:把所有空格都替换成 "%20"
//方法1
string s3("hello world hello C++");
for (size_t i = 0; i < s3.size();)
{if (s3[i] == ' '){s3.replace(i, 1, "%20");i += 3;}else{i++;}
}
cout << s3 << endl;//方法二
string s4("hello world hello C++");
string s5;
for (auto ch : s4)
{if (ch != ' '){s5 += ch;}else{s5 += "%20";}
}}

int main()
{string url("https://legacy.cplusplus.com/reference/string/string/substr/");size_t pos1 = url.find(':');string url1 = url.substr(0, pos1 - 1);cout << url1 << endl;size_t pos2 = url.find('/', pos1 + 3);string url2 = url.substr(pos1 + 3, pos2 - (pos1 + 3));cout << url2 << endl;string url3 = url.substr(pos2 + 1);cout << url3 << endl;return 0;
}

string类非成员函数

函数功能说明
operator+尽量少用,因为传值返回,导致深拷贝效率低
operator>> 输入运算符重载
operator<< 输出运算符重载
getline 获取一行字符串


 

int main()
{string s1 = "hello";string s2 = "world";string ret = s1 + s2;cout << ret << endl;string ret2 = s1 + "xxxxx";cout << ret2 << endl;//第三种用法就是为什么要将operator+ 设置成非成员函数的原因string ret3 = "xxxxx" + s2;cout << ret3<< endl;return 0;
}

最后我们来看一下getline 

这个函数我们要搭配一道题来看:

字符串最后一个单词的长度_牛客题霸_牛客网

这道题,我们可能会这么写:

int main() 
{string str;cin>>str;size_t pos = str.rfind(' ');cout << str.size() - (pos+1) << endl;return 0;
}

但是,这样写的结果是:

为什么?因为它遇到空格就结束了,cin或者scanf默认规定空格或者换行是多个值的分割

那么,如何才能完整的提取呢 ?

接下来我们看一下getline

它是默认遇到换行才结束,当然,这个结束符也可以由我们来 自定义

知道了getline,我们就可以将上面的代码进行修改

int main() 
{string str;getline(cin, str); size_t pos = str.rfind(' ');cout << str.size() - (pos+1) << endl;return 0;
}

总结

对于string类的常用接口使用我们就先说到这里,另外,值得在这里强调对于一些接口的使用我们可以去查文档进行理解使用。


http://www.mrgr.cn/p/36767271

相关文章

第十届山东省大学生程序设计竞赛题解(A、F、M、C)

部分代码define了long long,请记得开long long A. Calandar 把年份、月份、单个的天数全都乘以对应的系数转化成单个的天数即可,注意最后的结果有可能是负数,要转化成正数。发现技巧是:(ans % 5 + 5) % 5。? 还有注意不能这样写,答案不正确。或许是因为取模运算没有这样的…

jmeter后置处理器提取到的参数因为换行符导致json解析错误

现象&#xff1a; {"message":"JSON parse error: Illegal unquoted character ((CTRL-CHAR, code 10)): has to be escaped using backslash to be included in string value; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Ill…

网页主题自动适配:网页跟随系统自动切换主题

主题切换是网站设计中一个非常有趣的功能&#xff0c;它允许用户在多种预先设计的样式之间轻松切换&#xff0c;以改变网站的视觉表现。最常见的就是白天和黑夜主题的切换&#xff0c;用户可以根据自己的喜好进行设置。 除了让用户手动去切换主题外&#xff0c;如果能够让用户第…

(七)JSP教程——session对象

浏览器和Web服务器之间的交互通过HTTP协议来完成&#xff0c;HTTP协议是一种无状态的协议&#xff0c;服务器端无法保留浏览器每次与服务器的连接信息&#xff0c;无法判断每次连接的是否为同一客户端。为了让服务器端记住客户端的连接信息&#xff0c;可以使用session对象来记…

基于springboot+jsp+Mysql的商务安全邮箱邮件收发

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

定时将系统时间更新在日志文件中

获取当前系统时间,把时间转换为特定格式”yy年mm月dd日 星期x tt:mm:ss”,并每隔1s写入到本地磁盘中一个叫做log.txt的文本中,如果文本不存在则创建V1.0 2024年5月9日 发布于博客园实现:设计程序,获取当前系统时间,把时间转换为特定格式”yy年mm月dd日 星期x tt:mm:ss”,…

jQuery-1.语法、选择器、节点操作

jQuery jQueryJavaScriptQuery&#xff0c;是一个JavaScript函数库&#xff0c;为编写JavaScript提供了更高效便捷的接口。 jQuery安装 去官网下载jQuery&#xff0c;1.x版本练习就够用 jQuery引用 <script src"lib/jquery-1.11.2.min.js"></script>…

RK3568 学习笔记 : u-boot 千兆网络无法 ping 通PC问题的解决方法二

参考 RK3568 学习笔记 : u-boot 千兆网络无法 ping 通PC问题的解决 前言 rk3568 rockchip 提供的 u-boot&#xff0c;默认的设备树需要读取 单独分区 resouce.img 镜像中的 设备树文件&#xff0c;也就是 Linux 内核的设备树 dtb 文件&#xff0c;gmac 网络才能正常的 ping 通…

Marin说PCB之国产电源芯片方案 ---STC2620Q

随着小米加入的造车大家庭&#xff0c;让这个本来就卷的要死的造车大家庭更加卷了。随之带来的蝴蝶效应就是江湖上各个造成门派都开始了降本方案的浪潮啊&#xff0c;开始打响价格战了。各家的新能源车企也是不得不开始启动了降本方案的计划了&#xff0c;为了应对降价的浪潮。…

3月空气净化器市场数据分析,热门品牌排行榜揭晓!

三月上旬以来&#xff0c;中国空气净化器行业的规模持续扩大&#xff0c;市场规模和消费需求也在不断提升&#xff0c;消费者对高质量空气的需求增加。智能化是当前空气净化器市场的一个重要发展方向&#xff0c;这类产品集成了空气过滤、监测等功能&#xff0c;满足了现代消费…

Linux0.11中MINIX 文件系统

阅读linux 的源码的时候对minix 文件系统有很多的疑惑&#xff0c;根据自己的认识将这些做一个总结。 MINIX 文件系统由六个部分组成&#xff0c;分别是引导块&#xff0c;超级块&#xff0c;i结点位图&#xff0c;逻辑块位图&#xff0c;i结点&#xff0c;数据块。 引导块&am…

【动态规划】:路径问题_地下城游戏

朋友们、伙计们&#xff0c;我们又见面了&#xff0c;本专栏是关于各种算法的解析&#xff0c;如果看完之后对你有一定的启发&#xff0c;那么请留下你的三连&#xff0c;祝大家心想事成&#xff01; C 语 言 专 栏&#xff1a;C语言&#xff1a;从入门到精通 数据结构专栏&…

ChatPPT开启高效办公新时代,AI赋能PPT创作

目录 一、前言二、ChatPPT的几种用法1、通过在线生成2、通过插件生成演讲者模式最终成品遇到问题改进建议 三、ChatPPT其他功能 一、前言 想想以前啊&#xff0c;为了做个PPT&#xff0c;我得去网上找各种模板&#xff0c;有时候还得在某宝上花钱买。结果一做PPT&#xff0c;经…

【driver2】设备读写,同步和互斥,ioctl,进程休眠,时间和延时,延缓

文章目录 1.实现设备读写&#xff1a;write函数中一个进程写没问题&#xff0c;两进程写&#xff1a;第一个进程运行到kzalloc时&#xff0c;第二个进程也执行了kzalloc&#xff0c;只第二个进程地址保存在c中&#xff0c;第一个进程分配内存空间地址丢失造成内存泄漏。第一个进…

Spring-依赖来源

依赖来源 1 Spring BeanDefinition&#xff08;xml,注解&#xff0c;BeanDefinitionBuilder, 还有API实现的单例对象&#xff09; 2 Spring 内建BeanDefinition 3 内建单例对象 依赖注入和依赖查找的区别 Context.refresh() 的时候会调用这个方法&#xff1a;prepareBeanF…

微服务---gateway网关

目录 gateway作用 gateway使用 添加依赖 配置yml文件 自定义过滤器 nacos上的gateway的配置文件 我们现在知道了通过nacos注册服务&#xff0c;通过feign实现服务间接口的调用&#xff0c;那对于不同权限的用户访问同一个接口&#xff0c;我们怎么知道他是否具有访问的权…

FileLink文件摆渡技术解析:如何实现数据的安全摆渡与隔离

文件摆渡系统&#xff0c;这一现代科技名词&#xff0c;蕴含着深刻的科技内涵和广泛的应用前景。简而言之&#xff0c;文件摆渡系统是一种高效、安全的文件传输工具&#xff0c;它能够在不同的网络环境之间实现文件的快速、稳定传输。在今天的数字化时代&#xff0c;随着数据量…

Linux(openEuler、CentOS8)企业内网DHCP服务器搭建(固定Mac获取指定IP)

----本实验环境为openEuler系统<以server方式安装>&#xff08;CentOS8基本一致&#xff0c;可参考本文&#xff09;---- 目录 一、知识点二、实验&#xff08;一&#xff09;为服务器配置网卡和IP&#xff08;二&#xff09;为服务器安装DHCP服务软件&#xff08;三&a…

【JAVA】类加载过程,以及类加载器

类加载过程&#xff0c;以及类加载器 一、类加载的过程二、类加载器介绍三、跨类加载三、举例说明 一、类加载的过程 类加载是Java虚拟机&#xff08;JVM&#xff09;将类文件加载到内存中并转换成对应的类对象的过程。它确保了类文件能够正确加载并转换成可执行的类对象&…

【半个月我拿下了软考证】软件设计师高频考点--系统化教学-网络安全

&#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;软件设计师考点暴击 ⭐&#x1f170;️进入狂砍分⭐ ⭐软件设计师高频考点文档&#xff0c; ⭐软件设计师高频考点专栏 ⭐软件设计师高频考点⭐ &#x1f3b6;&#xff08;A) 考点1&#xff0c;网络攻击 理解记忆 &#…