string容器的常用操作

news2025/2/26 5:22:02

string容器的常用操作

  • 一、C语言中的字符串
  • 二、string容器
    • 1、概念
    • 2、特点
  • 三、string类对象的常见构造
    • 1、构造
    • 2、实际构造函数
    • 3、测试代码
    • 4、运行结果
  • 四、赋值运算符
    • 1、类型
    • 2、作用
    • 3、测试代码
    • 4、运行结果
  • 五、string类对象的容量操作
    • 1、成员函数
    • 2、测试代码
    • 3、说明
    • 4、运行结果
  • 六、运算符[]
    • 1、类型
    • 2、作用
    • 3、测试代码
    • 4、运行结果
    • 5、错误代码与编译器报错
  • 七、迭代器
    • 1、类型
    • 2、概念
    • 3、测试代码
    • 4、运行结果
    • 5、总结
  • 八、增加字符的函数
    • 1、类型
    • 2、作用
    • 3、测试代码
    • 4、运行结果
    • 5、总结
  • 九、c_str
    • 1、类型
    • 2、作用
    • 3、测试代码
    • 4、运行结果
    • 5、总结
  • 十、搜寻与截取
    • 1、类型
    • 2、作用
    • 3、测试代码
    • 4、运行结果

一、C语言中的字符串

在C语言中,字符串是以\0结尾的一串字符的集合,而为了操作方便,C标准库中提供了一些str系列的库函数,比如,strcpy、strlen、strcmp等等。但是这些库函数与字符串是分离开的,不太符合OOP的思想(面向对象编程(Object Oriented Programming)),而且底层空间需要用户自己管理,稍不留神可能就会有越界访问的问题发生。

二、string容器

1、概念

string容器是c++中表示字符序列的一个类,同时也是一个类模板。它提供了许多成员函数和运算符重载,封装了C++中对字符串的常见操作和功能,提供了更高级的字符串处理能力,并且隐藏了底层的实现细节,使得字符串的操作更加方便和安全。但string类是一个泛型类,它是由模板实例化出来的一个标准类,本质上不是一个标准数据类型。详情参见上方string容器文档。

2、特点

  • 标准的字符串类提供了对此类对象的支持,其接口类似于标准字符容器的接口,但添加了专门用于操作单字节字符和字符串的设计特性。
  • string类是basic_string模板类的一个实例,它使用char作为basic_string模板类的类型去实例化,并用char_traits和allocator作为basic_string的默认参数(模板的概念参见模板和STL简介)。
  • string类处理字节与使用的编码无关。即如果用于处理多字节或可变长度字符(如 UTF-8)的序列,则此类的所有成员(如长度或大小)及其迭代器仍将以字节(而不是实际编码字符)为单位运行。
  • 在使用string类时,必须用#include包含它的头文件string以及使用标准命名空间std。

三、string类对象的常见构造

1、构造

常用构造函数名称功能说明
string()创建一个空的string类对象,即空字符串
string(const char* s)用C语言格式的字符串来构造string类对象
string(size_t n, char c)创建一个包含n个字符c的string类对象
string(const string& str)string类的拷贝构造函数,用对象str创建一个string类对象

2、实际构造函数

在这里插入图片描述

3、测试代码

#include<iostream>
#include<string>
using namespace std;

void Test_string1()
{
    string s1;
    cout << s1 << endl;

    string s2("snow dragon");
    cout << s2 << endl;

    string s3(6, 's');
    cout << s3 << endl;

    string s4(s2);
    cout << s4 << endl;
}

int main()
{
	try
	{
		Test_string1();
	}
	catch (const std::exception& e)
	{
		cout << e.what() << endl;
	}
	
	return 0;
}
  • main函数中的try与catch的作用是捕获异常。

4、运行结果

在这里插入图片描述

四、赋值运算符

1、类型

在这里插入图片描述

2、作用

=运算符用一个新值为string对象的字符串赋值,它会替换掉string对象字符串之前的内容。

3、测试代码

int main()
{
	string s1;
	string s2 = "snow dragon"; // 调用构造函数 + 拷贝构造 -> 编译器优化 --> 直接调用构造函数创建对象s2
	
	cout << s1 << endl;
	cout << s2 << endl;

	s1 = s2;
	cout << s1 << endl;

	s1 = "ssss";
	cout << s1 << endl;

	s1 = 's';
	cout << s1 << endl;

	return 0;
}

4、运行结果

在这里插入图片描述

五、string类对象的容量操作

1、成员函数

函数名称功能说明
size_t size() const;返回字符串的长度(以字节为单位)。
size_t capacity() const;返回当前为字符串分配的存储空间的大小,以字节表示。
bool empty() const;返回字符串是否为空,即其长度是否为 0。
void clear();擦除字符串的内容,该字符串将成为空字符串(长度为 0 个字符)。
void reserve (size_t n = 0);请求更改容量的大小,对字符串(对象)长度没有影响,并且无法更改其内容。
void resize (size_t n);void resize (size_t n, char c);将字符串的大小调整为n个字符的长度,即修改size。

2、测试代码

void Test_string2()
{
    string s1("snow");
    cout << s1 << endl;
    cout << s1.size() << endl;
    cout << s1.capacity() << endl;
    cout << s1.empty() << endl;

    cout << "***************************" << endl;

    string s2;
    cout << s2.empty() << endl;

    cout << "***************************" << endl;

    string s3("snow");
    cout << s3 << endl;
    cout << s3.size() << endl;
    s3.resize(10, '!');
    cout << s3 << endl;
    cout << s3.size() << endl;
    s3.resize(3);
    cout << s3 << endl;
    cout << s3.size() << endl;

    cout << "***************************" << endl;

    string s4;
    s4.reserve(100);
    cout << s4.size() << endl;
    cout << s4.capacity() << endl;

    s4.reserve(50);
    cout << s4.size() << endl;
    cout << s4.capacity() << endl;

    cout << "***************************" << endl;

    s1.clear();
    cout << s1 << endl;
    cout << s1.size() << endl;
    cout << s1.capacity() << endl;
}

3、说明

  • string类对象的容量操作函数中其实还有函数size_t length() const。只不过它不常用,并且size()与length()函数的底层实现原理完全相同,这里引入size()的原因是为了与其他容器的接口保持一致,一般情况下基本都是使用函数size()。
  • 函数clear()只是将string中有效字符清空,即将string对象中的字符串清空时,只是将size置为0,但不改变对象的底层空间大小。
  • resize(size_t n) 与 resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不同的是当字符个数增多时:resize(n)是用0来对多出的空间的元素进行赋值,resize(size_t n, char c)是用字符c来对多出的空间的元素进行赋值。
  • resize在改变元素个数时,如果是将元素个数增多,可能会改变容量空间的大小,如果是将元素个数减少,则它的容量空间不会改变。
  • reserve(size_t res_arg=0);的作用是为string对象预留空间,它不改变有效元素个数,即对容量空间大小进行处理。但当reserve的参数小于string的容量空间总大小时,reserver不会改变容量空间的大小。

4、运行结果

在这里插入图片描述

六、运算符[]

1、类型

在这里插入图片描述

2、作用

返回string对象字符串下标为pos的字符的引用。

3、测试代码

void Test2()
{
	string s1("snow dragon");
	cout << s1[0] << endl;
	cout << s1 << endl;

	s1[0] = 'h';
	cout << s1[0] << endl;
	cout << s1 << endl;

	//遍历string对象并对它的每个字符+1
	for (size_t i = 0; i < s1.size(); ++i)
	{
		s1[i]++;
	}
	cout << s1 << endl;

	const string s2("dragon");
	for (size_t i = 0; i < s2.size(); ++i)
	{
		//s2[i]++;
		cout << s2[i] << " ";
	}
	cout << endl;
	cout << s2 << endl;

	//cout << s2[10] << endl;			//编译器内部会检查是否越界
}

4、运行结果

在这里插入图片描述

5、错误代码与编译器报错

在这里插入图片描述

七、迭代器

1、类型

在这里插入图片描述

2、概念

迭代器是一种检查容器内的元素并遍历元素的数据类型,通常用于对C++中各种容器内的元素进行访问。

3、测试代码

void Test3()
{
	cout << "s1 test" << endl;
	string s1("snow");
	cout << s1 << endl;
	string::iterator it1 = s1.begin();
	while (it1 != s1.end())
	{
		(*it1)++;
		cout << *it1 << " ";
		++it1;
	}
	cout << endl;

	//范围for: 自动迭代,自动判断结束。底层其实就是迭代器
	//下方为使用范围for依次取s1中的每个字符并赋值给ch,再将ch自增1,最后输出
	for (auto& ch : s1)
	{
		ch++;
		cout << ch << " ";
	}
	cout << endl;

	cout << s1 << endl;


	cout << "s2 test" << endl;

	string s2("snow dragon");
	cout << s2 << endl;
	string::reverse_iterator rit2 = s2.rbegin();
	while (rit2 != s2.rend())
	{
		cout << *rit2 << " ";
		++rit2;
	}
	cout << endl;


	cout << "s3 test" << endl;

	const string& s3("snow dragon");
	cout << s3 << endl;
	//string::const_iterator it3 = s3.begin();
	auto it3 = s3.begin();
	while (it3 != s3.end())
	{
		//*it3 = 'x';
		cout << *it3 << " ";
		++it3;
	}
	cout << endl;


	cout << "s3 reverse iterator test" << endl;

	//auto rit3 = s3.rbegin();
	string::const_reverse_iterator rit3 = s3.rbegin();
	while (rit3 != s3.rend())
	{
		cout << *rit3 << " ";
		++rit3;
	}
	cout << endl;
}

4、运行结果

在这里插入图片描述

5、总结

  • string和vector都不喜欢用iterator,因为[]更好用,而list、map和set等等只能用迭代器进行访问。
  • iterator是所有容器通用的访问方式,即所有容器的用法都是类似的。
  • iterator的用法像指针一样,它的底层实现有可能就是用指针实现的,也有可能不是,具体要看容器本身。

八、增加字符的函数

1、类型

在这里插入图片描述

2、作用

  • push_back是在string对象字符串的末尾添加一个字符。
  • append是在string对象字符串的末尾添加一个字符串。
  • +=运算符是在string对象字符串的末尾添加一个字符或字符串。
  • 它们三个将改变字符串的实际大小size和容量空间,如果string对象字符串的容量空间不足,它们会自动对string对象字符串进行增容。

3、测试代码

void Test4()
{
	string s("snow");
	s.push_back('-');
	s.push_back('-');
	s.append("dragon");
	cout << s << endl;

	string str("coming");
	s += '@';
	s += str;
	s += "!!!";
	cout << s << endl;

	s.append(++str.begin(), --str.end());
	cout << s << endl;

	string copy1(++s.begin(), --s.end());
	cout << copy1 << endl;

	string copy2(s.begin() + 5, s.end() - 5);
	cout << copy2 << endl;
}

4、运行结果

在这里插入图片描述

5、总结

  • 在string尾部追加字符时,s.push_back( c ) / s.append(1, c) / s += 'c’三种实现方式是差不多的。
  • 一般情况下string类的+=操作用的比较多,因为它不仅可以连接单个字符,还可以连接字符串。

九、c_str

1、类型

在这里插入图片描述

2、作用

c_str将调用它的string对象字符串转换为一个字符数组,该数组是以\0结尾的,最后返回指向这个数组的指针。

3、测试代码

void Test5()
{
	string name("snow");
	cout << name << endl;
	cout << name.c_str() << endl;

	name += '\0';
	name += "dragon";
	cout << name << endl;
	cout << name.c_str() << endl;

	cout << name.size() << endl;
	string copy = name;
	cout << copy << endl;

	cout << '\0' << endl;
	cout << "end" << endl;
}

4、运行结果

在这里插入图片描述

5、总结

  • string对象字符串的大小是由它的实际大小size决定的,当输出时,将输出到下标为size - 1时才结束,因为下标为size处的值为\0。
  • 当输出string对象时,\0默认是不输出的。
  • 常量字符串对象或用string对象转换为C类型的字符串时,字符串的结束标志是\0。

十、搜寻与截取

1、类型

在这里插入图片描述

2、作用

  • find是在字符串中搜索其第一个形参,如果在string对象(字符串)中找到了,则返回开始匹配处的下标;当形参pos指定时,find只搜索字符串下标位置pos处和它之后的字符,pos之前的字符不搜寻;当搜索多个字符时,即find的第一个形参是个字符串时,在string对象中搜寻的序列需要和该形参整个序列都匹配才行。
  • rfind与find类似,只是它从字符串的尾部开始搜寻,pos指定时和find的搜寻顺序相反。
  • substr在调用它的对象的字符串中,从pos位置开始,截取len个字符,然后用截取到的字符序列创建一个string对象并将其返回。
  • npos是一个静态成员常量值,是类型size_t的最大值。当它在字符串的成员函数中用作len(或 sublen)参数的值时,表示直到字符串结束为止。当它作为返回值时,通常用于表示没有找到匹配项。

3、测试代码

void DealUrl(const string& url)
{
	size_t pos1 = url.find("://");
	if (pos1 == string::npos)
	{
		cout << "非法url" << endl;
		return;
	}
	
	string protocol = url.substr(0, pos1);
	cout << protocol << endl;

	size_t pos2 = url.find('/', pos1 + 3);
	if (pos2 == string::npos)
	{
		cout << "非法url" << endl;
		return;
	}
	string domain = url.substr(pos1 + 3, pos2 - pos1 - 3);
	cout << domain << endl;

	string uri = url.substr(pos2 + 1);
	cout << uri << endl;
}

void Test6()
{
	string name("snow.dragon.happy.everyday");
	
	//输出前缀
	size_t pos = name.find('.');
	if (pos != string::npos)
	{
		string suff = name.substr(0, pos);
		cout << suff << endl;
	}

	//输出后缀
	pos = name.rfind('.');
	if (pos != string::npos)
	{
		string suff = name.substr(pos);
		cout << suff << endl;
	}

	string url1 = "https://legacy.cplusplus.com/reference/string/string/find/";
	cout << url1 << endl;
	DealUrl(url1);
}

4、运行结果

在这里插入图片描述

本文到这里就结束了,如有错误或者不清楚的地方欢迎评论或者私信
创作不易,如果觉得博主写得不错,请务必点赞、收藏加关注💕💕💕

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

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

相关文章

第二十章 ObjectScript - 潜在的缺陷

文章目录 第二十章 ObjectScript - 潜在的缺陷 第二十章 ObjectScript - 潜在的缺陷 以下项目可能会让刚接触ObjectScript的程序员感到困惑&#xff0c;特别是那些负责维护其他程序员编写的代码的程序员: 在例程或方法中&#xff0c;除非每行包含标签&#xff0c;否则每行必须…

复制粘贴是怎么实现的

在上面的代码中&#xff0c;command 和 select 是自定义的函数。它们的作用如下&#xff1a; 实现复制粘贴的思路&#xff1a; 创建一个 textarea 标签将 textarea 移出可视区域给这个 textarea 赋值将这个 textarea 标签添加到页面中调用 textarea 的 select 方法调用 docum…

【PowerDesigner16】显示工具面板

1、点击左上角【工具】“toolbars”&#xff0c;然后【自定义工具栏】&#xff0c;选择“palette”即可显示工具栏。

MediaCodec源码分析 createByCodecName流程

前言 本文梳理MediaCodec初始化流程,即create流程,基于7.0代码。流程图如下,创建流程还是比较清晰简单的。 代码见: frameworks/base/media/java/android/media/MediaCodec.java frameworks/base/media/jni/android_media_MediaCodec.h frameworks/base/media/jni/androi…

源代码防泄密

IBM 发布年度《数据泄露成本报告》&#xff0c;显示 2023 年全球数据泄露平均成本达到 445 万美元&#xff0c;比过去 3 年增加了 15%。创下该报告的历史新高。 报告显示&#xff0c;企业在计划如何应对日益增长的数据泄露频率和成本方面存在分歧。研究发现&#xff0c;虽然 95…

Debian12系统下LAMP环境中Nubuilder4.5的安装

一、环境搭建 按照官方的说法&#xff0c;Apache2和Nginx都可以的&#xff0c;实际上&#xff0c;你最好直接按照 Mariadb\Apache2\Php8.2 这个顺序&#xff0c;搭建LAMP环境较好。不然各种调试&#xff0c;还不一定能够成功。 相关搭建方法&#xff0c;属于一般操作&#xf…

Python关键字(保留字)一览表

保留字是 Python 语言中一些已经被赋予特定意义的单词&#xff0c;这就要求开发者在开发程序时&#xff0c;不能用这些保留字作为标识符给变量、函数、类、模板以及其他对象命名。 Python 包含的保留字可以执行如下命令进行查看&#xff1a; >>> import keyword >…

刷题笔记16——数组的花式输出

华容道 听到面试的时候会问到华容道的问题&#xff0c;简单记录一下&#xff0c;也类似于迷宫问题&#xff0c;可以记录下空格地方所在的位置&#xff0c;华容道问题就类似于空格在整个数组中寻找一条路线&#xff08;无论我们如何移动小块&#xff0c;其实都是空格以一条路线…

ActiveReportsJs 账票印刷

参考资料 官方文档 一. HTML部分 在页面上添加了Loading效果&#xff0c;账票印刷开始时显示Loading效果&#xff0c;印刷结束后隐藏Loading效果。ar-js-core.js是核心文件ar-js-pdf.js用来印刷PDFar-js-xlsx.js用来印刷EXCELar-js-locales.js用来设置语言 <!DOCTYPE htm…

MySQL——数据类型以及对表结构的修改

MySQL的数据类型 刚才我们在创建表的时候&#xff0c;说到了一个字段类型&#xff0c;所谓的字段类型就是这个字段能存放的数据的数据类型&#xff0c;在MySQL中有以下几种数据类型&#xff1a; 数据类型 大小&#xff08;字节&#xff09; 用途 格式 INT 4 整数 FLOAT…

13 - 多线程之锁优化(中):深入了解Lock同步锁的优化方法

上一讲介绍了在 JVM 层实现的 Synchronized 同步锁的优化方法&#xff0c;除此之外&#xff0c;在 JDK1.5 之后&#xff0c;Java 还提供了 Lock 同步锁。那么它有什么优势呢&#xff1f; 相对于需要 JVM 隐式获取和释放锁的 Synchronized 同步锁&#xff0c;Lock 同步锁&#…

echarts legend如何控制标签文字长度

效果 代码&#xff0c;直接贴进去换掉就能测试 legend: {type: scroll,top: 10%,icon: circle,right: 5%,orient: vertical,formatter:(name)>{//下面三个值换一下就行let arr [{a| 科创团队 },{b| 10 个},{c| 100 %}]return arr.join( )},textStyle: { color: #C2…

java实现创建时间、修改时间自动生成

一、TbaleMetaObjectHandler package com.ybzx.zdbx.common.handler;import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; import lombok.extern.slf4j.Slf4j; import org.apache.ibatis.reflection.MetaObject; import org.springframework.stereotype.Compo…

一文了解Android App Bundle 格式文件

1. Android App Bundle 是什么&#xff1f; 从 2021 年 8 月起&#xff0c;新应用需要使用 Android App Bundle 才能在 Google Play 中发布。 Android App Bundle是一种发布格式&#xff0c;打包出来的格式为aab&#xff0c;而之前我们打包出来的格式为apk。编写完代码之后&a…

PowerDesginer提示打印机错误

PowerDesginer提示打印机错误 错误信息&#xff1a;在您可以执行与打印机有关的任务(例如页面设置或打印一个文档)之前,您必须已经安装打印机。您想现在安装打印机么&#xff1f; 运行 >services.msc> Print Spooler 启动服务

JSON是什么?认识 json

目录 一 Json定义 二 Json语法规则 三 json 的代码演示 一 Json定义 轻量级的文本数据交换格式具有自我描述性【看到某个Json数据就能知道它的特点】比xml传输速度快【跨平台】 二 Json语法规则 &#xff08;1&#xff09;语法 两种数据结构&#xff1a;对象和数组 大括号…

LGFormer:LOCAL TO GLOBAL TRANSFORMER FOR VIDEO BASED 3D HUMAN POSE ESTIMATION

基于视频的三维人体姿态估计的局部到全局Transformer 作者&#xff1a;马海峰 *&#xff0c;陆克 * †&#xff0c;薛健 *&#xff0c;牛泽海 *&#xff0c;高鹏程† * 中国科学院大学工程学院&#xff0c;北京100049 鹏程实验室&#xff0c;深圳518055 来源&#xff1a;202…

cartographer 学习

cartographer 学习 编译并运行代码 由于cartographer整体分成了两个包 一个是cartographer,不带ros的内容另一个是cartographer_ros&#xff0c;是已ros项目构建的 这样因为带了普通cmake的包&#xff0c;就没法使用catkin_make了&#xff0c;只能使用catkin_make_isolated …

Global mapper24.1最新中文版本教程以及安装包

Global mapper成为如此用户友好的数据编辑、分析等工具的部分原因是它如何处理已删除的要素。从撤消管理器到独立工作空间&#xff0c;已删除的功能并不总是消失。矢量特征以一种简单的方式&#xff0c;当您在需要时遇到它时几乎感觉像魔术一样&#xff0c;矢量特征存储在工作区…

【python基础知识】8.编程思维:如何解决问题-思维篇

文章目录 前言瓶颈1&#xff1a;知识学完就忘用法查询笔记深度理解笔记知识管理 瓶颈2&#xff1a;缺乏解题能力如何解题分析问题&#xff0c;明确结果思考需要的知识&#xff0c;或搜索新知识思考切入点尝试解决问题的一部分尝试重复1-4步 总结 前言 Hi&#xff0c;欢迎来到第…