string 类

一、为什么学习 string 类

1、C语言中的字符串


C语言中,字符串是以'\0'结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列
的库函数,但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户
自己管理,稍不留神可能还会越界访问
 

2、在日常中

在OJ中,有关字符串的题目基本以string类的形式出现,而且在常规工作中,为了简单、方便、
快捷,基本都使用string类,很少有人去使用C库中的字符串操作函数
 

二、标准库中的string类

1.string 类

string类的文档介绍

https://cplusplus.com/stringicon-default.png?t=O83Ahttps://cplusplus.com/string在使用string类时,必须包含#include头文件 #include<string>

以及using namespace std;
 

2 auto和范围for


(1)auto关键字


在这里补充2个C++11的小语法,方便我们后面的学习。


     在早期C/C++中auto的含义是:使用auto修饰的变量,是具有自动存储器的局部变量,后来这个不重要了。C++11中,标准委员会变废为宝赋予了auto全新的含义即:auto不再是一个存储类型
指示符,而是作为一个新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译时期
推导而得。

    用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则必须加&
当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错,因为编译器实际
只对第一个类型进行推导,然后用推导出来的类型定义其他变量。
   auto不能作为函数的参数,可以做返回值,但是建议谨慎使用
   auto不能直接用来声明数组


#include<iostream>
using namespace std;int func1()
{return 10;
}不能做参数
//void func2(auto a)
//{}// 可以做返回值,但是建议谨慎使用
auto func3()
{return 3;
} int main()
{int a = 10;auto b = a;//自动推导为int 类型auto c = 'a'; //自动推导为char类型auto d = func1();//函数返回值编译报错:rror C3531: “e”: 类型包含“auto”的符号必须具有初始值设定项//auto e;cout << typeid(b).name() << endl;cout << typeid(c).name() << endl;cout << typeid(d).name() << endl;int x = 10;auto y = &x; //y为int 类型auto* z = &x;//z为指针类型auto& m = x; //m为引用类型cout << typeid(x).name() << endl;cout << typeid(y).name() << endl;cout << typeid(z).name() << endl;//auto aa = 1, bb = 2;编译报错:error C3538: 在声明符列表中,“auto”必须始终推导为同一类型//auto cc = 3, dd = 4.0;// 编译报错:error C3318: “auto []”: 数组不能具有其中包含“auto”的元素类型/*auto array[] = { 4, 5, 6 };*/return 0;
}

运行结果:

说明:auto声明引用类型时则必须加&,否则就是原来变量的类型。

一个例子说明auto的方便

#include<iostream>
#include <string>
#include <map>
using namespace std;
int main()
{std::map<std::string, std::string> dict = { { "apple", "苹果" },{ "orange","橙子" }, {"pear","梨"} };// auto的用武之地//std::map<std::string, std::string>::iterator it = dict.begin();auto it = dict.begin();while (it != dict.end()){cout << it->first << ":" << it->second << endl;++it;}return 0;
}

 

(2)范围for

      对于一个有范围的集合而言,由程序员来说明循环的范围是多余的,有时候还会容易犯错误。因此C++11中引入了基于范围的for循环for循环后的括号由冒号“ :”分为两部分第一部分是范围内用于迭代的变量,第二部分则表示被迭代的范围,自动迭代,自动取数据,自动判断结束。
     范围for可以作用到数组和容器对象上进行遍历
     范围for的底层很简单,容器遍历实际就是替换为迭代器,这个从汇编层也可以看到
 

//范围for C++11
//自动取容器的数据赋值给左边的对象
//自动++,自动判断结束
//原理:范围for的底层是迭代器

遍历数组:

#include<iostream>
#include <string>
#include <map>
using namespace std;
int main()
{int array[] = { 1, 2, 3, 4, 5 };// C++98的遍历for (int i = 0; i < sizeof(array) / sizeof(array[0]); ++i){array[i] *= 2;} for (int i = 0; i < sizeof(array) / sizeof(array[0]); ++i){cout << array[i] <<" ";} cout << endl;// C++11的遍历for (auto& e : array)//冒号左边是范围内用于迭代的变量。右边是被迭代的范围e *= 2;for (auto e : array)cout << e << " " ;return 0;
}

结果:

 注意:如果使用范围for的遍历时,想改变数组的值,冒号左边用于迭代的变量的类型要是:

引用类型,才可以改变值,否则无法改变(因为改变的只是拷贝,并不是其本身)

	for (auto& e : array)//冒号左边是范围内用于迭代的变量。右边是被迭代的范围

当不加&符号时

#include<iostream>
#include <string>
#include <map>
using namespace std;
int main()
{int array[] = { 1, 2, 3, 4, 5 };// C++11的遍历for (auto e : array)//冒号左边是范围内用于迭代的变量。右边是被迭代的范围e *= 2;for (auto e : array)cout << e << " " ;return 0;
}

发现数组的值并没有发生改变

遍历字符数组:

#include<iostream>
#include <string>
#include <map>
using namespace std;
int main()
{string str("hello world");for (auto ch : str){cout << ch << " ";}return 0;
}

 

 (3)迭代器

begin指向第一个字符,end指向字符串末尾的'\0'

#include<iostream>
#include <string>
#include <map>
using namespace std;
int main()
{string str("hello world");//迭代器//string::iterator it1 = str.begin();auto it1 = str.begin();//可以使用auto,自动识别类型//begin指向字符h,end指向字符串末尾的'\0'while (it1 != str.end())//it1类似于指针{(*it1)++; //改变字符数组的字符it1++;}//范围for C++11//自动取容器的数据赋值给左边的对象//自动++,自动判断结束//原理:范围for的底层是迭代器for (auto ch : str)//自动识别类型{cout << ch << " ";}return 0;
}

结果:

hello world 的每个字符都加了1

(4)反向迭代器:

//string::reverse_iterator it = s1.rbegin();//reverse是翻转的意思

rbegin指向字符串的末尾那个字符
rend指向字符串首个字符的前一个位置

#include<iostream>
using namespace std;//  //  反向迭代器
//	//rbegin指向字符串的末尾那个字符
// 	//rend指向字符串首个字符的前一个位置
int main()
{string s1 = "hello zhouzisong";//string::reverse_iterator it = s1.rbegin();//reverse是翻转的意思auto it = s1.rbegin();//也可使用自动识别while (it != s1.rend()){cout << *it << " ";it++;  //反向迭代器也是使用++(从后往前移动)}return 0;
}

结果:

是从字符串的末尾开始移动的

#include<iostream>
#include <string>
#include <map>
using namespace std;
int main()
{string str("hello world");//迭代器//string::iterator it1 = str.begin();auto it1 = str.begin();//可以使用auto,自动识别类型//begin指向字符h,end指向字符串末尾的'\0'while (it1 != str.end())//it1类似于指针{(*it1)++; //改变字符数组的字符it1++;}//范围for C++11//自动取容器的数据赋值给左边的对象//自动++,自动判断结束//原理:范围for的底层是迭代器for (auto ch : str)//自动识别类型{cout << ch << " ";}//反向迭代器//rbegin指向字符串的末尾那个字符//rend指向字符串首个字符的前一个位置string::reverse_iterator rit= str.rbegin();//auto rit = str.rbegin();while (rit != str.rend()){(*rit)--;rit++;  //反向迭代器也是使用++(从后往前移动)}cout << endl;for (auto ch : str)//自动识别类型{cout << ch << " ";}return 0;
}

结果:

首先是正向的遍历字符串,将每个字符加1。后面又反向的遍历字符串,又将每个字符减1,回到原来的字符

(5)const 修饰时的迭代器

string::const_iterator it = s2.begin();
#include<iostream>
using namespace std;int main()
{string s1 = "hello world";const string s2=s1;//const修饰时string::const_iterator it = s2.begin();//auto it = s2.begin();//也可使用自动识别while (it != s2.end()){cout << *it << " ";it++;  }return 0;
}

注意:不能修改字符串

 

3. string类的常用接口说明(注意下面只讲解最常用的接口)

(1) string类对象的常见构造

 

(2). string类对象的容量操作

#include<iostream>
#include<string>
using namespace std;//capacity empty clear reserve resize
int main()
{string s1 = "abcdefg";string s2 = "";int size = s1.size();int length = s1.length();int capacity = s1.capacity();int s1_empty = s1.empty();int s2_empty = s2.empty();cout << "s1.size=" << size << endl << "s1.length=" << length << endl<<"s1.capacity="<<capacity<<endl;//size等于length,都是元素个数cout << "s1=" << s1_empty << endl;//结果为0,说明字符串s1不为空cout << "s2=" << s2_empty << endl;//结果为1,说明字符串s2为空s1.clear();cout << "调用clear()之后s1.size=" << s1.size() << endl;cout << "调用clear()之后s1.capacity=" << s1.capacity() << endl;s1 = "abcdefg";cout << s1 << endl;cout << "s1.capacity(原大小) =" << s1.capacity() << endl;s1.reserve(2);//括号里面是一个小于原字符串大小的数字(预留空间小了)cout << "s1.capacity(小) =" << s1.capacity() << endl;s1.reserve(20);//括号里面是一个小于原字符串大小的数字(预留空间大了)cout << "s1.capacity(大) =" << s1.capacity() << endl;string str("I like to code in C");//长度为19cout << str << '\n';unsigned sz = str.size();str.resize(sz + 2,'+');  //将会在原字符串后面添加2个+std::cout << str << '\n';str.resize(14);   //长度小于原字符串,会被截断,原字符串只剩下14个字符std::cout << str << '\n';return 0;
}

 结果:

 

 (3)string类对象的访问及遍历操作

operator[ ]的用法

#include<iostream>
#include<string>
using namespace std;
int main()
{string str = "abcd";int i;for (i = 0; str[i] != '\0'; i++){str[i]++; //每个字符都加1cout << str[i];}return 0;
}

 其他的函数用法见上:二、2

(4). string类对象的修改操作

 push_back 和 append 和operator+=的用法

#include<iostream>
#include<string>
using namespace std;
int main()
{string str1("abcde");string str2("abcde");string str3("abcde");string str4("abcde");cout<<"str1追加字符前" << str1 << endl;str1.push_back('s');cout << "str1追加字符后"<<str1 << endl;cout << "str2追加字符串前" << str2 << endl;str2.append("zzshewzh");cout << "str2追加字符串后" << str2 << endl;cout << "str3追加字符串str4前" << str3<< endl;str3 += str4;cout << "str3追加字符串str4后" << str3<< endl;return 0;
}

c_str()函数的用法:

c_str()函数返回一个指向正规C字符串的指针常量, 内容与本string串相同。
这是为了与c语言兼容,在c语言中没有string类型,故必须通过string类对象的成员函数c_str()把string 对象转换成c中的字符串样式。
注意:一定要使用strcpy()函数 等来操作方法c_str()返回的指针

c_str函数的返回值是const char*的,不能直接赋值给char*

#include<iostream>
#include<string>
using namespace std;int main()
{char c[20];string s = "1234";strcpy(c, s.c_str());//c_str()返回的是字符串的地址cout << c << endl; //打印字符数组cprintf("%s", s.c_str()); //直接根据地址,打印字符串return 0;
}

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

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

相关文章

3-GPIO八大输出模式 推挽输出 与 开漏输出

推挽输出 与 开漏输出 GPIO有八大输出模式 下图为每个GPIO口的基本结构&#xff1a; 通过这张图来学习 最右侧是I/O引脚&#xff0c;是从STM32引脚到GPIO口的导线&#xff0c;与其他芯片进行连接的线。 芯片内部电路所能承受的电压有限&#xff0c;当未知的静电进入GPIO口&a…

DBMS-3.3 SQL(3)——DML的INSERT、UPDATE、DELETE空值的处理DCL

本文章的素材与知识来自李国良老师和王珊老师。 DML——INSERT、UPDATE、DELETE 一. INSERT 1.语法 &#xff08;1&#xff09;INTO子句 &#xff08;2&#xff09;VALUES子句 &#xff08;3&#xff09;示例 2.插入子查询 若插入的是子查询则不需要VALUES子句 二. UPDATE …

一款电子产品图册转换器

​随着科技的不断发展&#xff0c;电子产品已经成为我们生活中不可或缺的一部分。无论是手机、平板电脑还是智能家居&#xff0c;它们都离不开电子图册的支撑。一款优秀的电子产品图册转换器&#xff0c;可以帮助我们轻松实现电子图册的转换&#xff0c;为我们的生活和工作带来…

还在为Python“运算符”中遇到的BUG而发愁吗?,变量相关的问题和解决办法看这篇文章就够了!

博客主页&#xff1a;长风清留扬-CSDN博客系列专栏&#xff1a;Python疑难杂症百科-BUG编年史每天更新大数据相关方面的技术&#xff0c;分享自己的实战工作经验和学习总结&#xff0c;尽量帮助大家解决更多问题和学习更多新知识&#xff0c;欢迎评论区分享自己的看法感谢大家点…

[SAP ABAP] LIKE TABLE OF

LIKE TABLE OF语句是用来参照结构体(工作区)对象定义内表数据类型的语句 在SAP ABAP中有标准表&#xff0c;排序表和哈希表三种内表数据类型 *定义标准表 DATA: <ty_tab_standard_name> LIKE [STANDARD] TABLE OF <dtype> [WITH NON-UNIQUE KEY <k1 k2 ... kn…

移动app的UI和接口自动化测试怎么进行?

标题&#xff1a;从0到1&#xff1a;移动App的UI和接口自动化测试 导语&#xff1a;移动App的快速发展使得UI和接口自动化测试成为了确保应用质量的重要环节。本文将从零开始介绍移动App的UI和接口自动化测试的基本概念以及如何进行测试。 第一部分&#xff1a;了解移动App自动…

MSYS2+GCC 安装与应用保姆手册

msys2 提供可在Windows下使用 GCC 编译器&#xff1b;并且&#xff0c;借助 Linux 包管理功能&#xff0c;可轻松下载丰富的可在Windows下直接使用的 C/C 开发包&#xff0c;包括编译好的二进制包。 网络库asio、准标准库boost、zip解压缩、json格式处理、引擎 SDL……十八般兵…

i春秋云境靶场之CVE-2022-26965

1.环境搭建 提示我们后台存在rce,也就是命令执行漏洞 2.访问环境 cm - cmshttp://eci-2zeh0yf0ohu88wr26unq.cloudeci1.ichunqiu.com/ 我们可看到admin,我们点击&#xff0c;发现是一个登录页面&#xff0c;我们输入弱口令admin,登录成功 3.文件上传 我们在选项——选择主题…

构造器和UML类图

1.构造器 1.1 详解 类的成员&#xff1a;构造器 构造器的作用 初始化对象&#xff1a;构造器用于设置对象的初始值&#xff0c;确保对象在创建时是有效的。提供灵活性&#xff1a;可以重载构造器&#xff0c;以便在创建对象时提供不同数量或类型的参数&#xff0c;从而支持…

[CR]厚云填补_条件扩散模型用于SAR到光学图像转换

Conditional Diffusion for SAR to Optical Image Translation Abstract 合成孔径雷达(SAR)提供全天候、全天高分辨率成像&#xff0c;但其独特的成像机制往往需要专家解释&#xff0c;限制了其广泛的适用性。为了应对这一挑战&#xff0c;提出了一个生成模型&#xff0c;该模型…

如何制作低代码开发的视频教程?

如何制作低代码开发的视频教程&#xff1f; 随着数字化转型的加速&#xff0c;越来越多的企业和组织开始采用低代码开发平台来加速应用程序的构建。对于许多开发者和业务人员来说&#xff0c;学习如何使用这些平台可以显著提高工作效率。因此&#xff0c;创建一份清晰、实用且…

JavaScript进阶--作用域-函数进阶

Javascript进阶 作用域 分类 局部 函数 >执行完变量被清空块 >用{}包住 >有可能被无法访问 【用var声明的变量】 全局 > 在script标签和.js文件最外层进行声明 作用域链 最底层的变量查找机制 > 在函数被执行时&#xff0c;会优先查找当前函数作用域中查找…

路径跟踪之导航向量场——二维导航向量场

今天带来一期轨迹跟踪算法的讲解&#xff0c;首先讲解二维平面中的导航向量场[1]。该方法具有轻量化、计算简便、收敛性强等多项优点。该方法根据期望的轨迹函数&#xff0c;计算全局位置的期望飞行向量&#xff0c;将期望飞行向量转为偏光角&#xff0c;输入底层控制器&#x…

【STM32单片机_(HAL库)】4-5-3【定时器TIM】【感应开关盖垃圾桶项目】项目实现

1.项目需求 以下几个事件触发时&#xff0c;垃圾桶自动开盖&#xff0c;并伴随蜂鸣器短响一声&#xff0c;同时 LED 灯闪烁一下&#xff0c;2秒后自动关盖&#xff1a; 检测到有人靠近检测到有震动按下按键 KEY1 2.硬件 STM32单片机最小系统震动传感器模块蜂鸣器模块&#…

CentOS 6文件系统

由冯诺依曼在 1945 年提出的计算机五大组成部分&#xff1a;运算器&#xff0c;控制器&#xff0c;存储器&#xff0c;输入设 备&#xff0c;输出设备。 1. 硬盘结构&#xff1a; &#xff08;1&#xff09;机械硬盘结构&#xff1a; 磁盘拆解图&#xff1a; 扇区&#xff0c;…

研发中台拆分之路:深度剖析、心得总结与经验分享

背景在 21 年&#xff0c;中台拆分在 21 年&#xff0c;以下为中台拆分的过程心得&#xff0c;带有一定的主观&#xff0c;偏向于中小团队中台建设参考&#xff08;这里的中小团队指 3-100 人的团队&#xff09;&#xff0c;对于大型团队不太适用&#xff0c;毕竟大型团队人中 …

UGUI(六大UI根基组件)

Rect Transform 各种参数 是显示pos还是width/height 还是left/top/right/bottom之类巴拉巴拉&#xff0c;各种混合的展示baby&#xff0c;都是看anchor的设置 pivot的设置影响具体数值 至于blueprint mode &#xff0c;就是用了之后框框不变&#xff0c;who wanna do thi…

理解PID(零)——什么是PID

PID控制器是一种广泛用于各种工业控制场合的控制器&#xff0c;它结构简单&#xff0c;可以根据工程经验整定参数Kp,Ki,Kd. 虽然现在控制专家提出了很多智能的控制算法&#xff0c;比如神经网络&#xff0c;模糊控制等&#xff0c;但是PID仍然被广泛使用。常见的PID控制器有位置…

开源全文搜索(搜索引擎)

吃水不忘挖井人&#xff0c;介绍Doug Cutting大牛是十分有必要的。 最早&#xff0c;接触到搜索引擎&#xff0c;知道有个Nutch&#xff08;开源搜索引擎&#xff09;&#xff0c;于是开始查看Nutch相关的资料&#xff0c;发现了Nutch的创始人Doug Cutting&#xff0c;随着项目…

初创公司首选HR软件推荐与功能解析

初创企业需HR软件自动化招聘、文书、日常任务及合规管理&#xff0c;提升效率。ZohoPeople是理想选择&#xff0c;性价比高&#xff0c;版本多样&#xff0c;满足不同需求。 1、简化招聘流程 您一直在寻找杰出的人才&#xff0c;以助您的初创企业飞跃发展。您选择的HR软件应该…