【C++】 —— string的使用

news2024/11/15 10:23:06

前言

        string类虽然不在STL的容器中,但string类十分重要,string类是对字符串的存储和相关操作。

        basic_string

        std::basic_string类是C++的一个模版类,它支持多种字符类型。

  1. char :用于表示一个字节的字符,使用ASCII编码。
  2. wchar_t :用于表示宽字符,可以支持更广泛的字符集。
  3. char8_t :用于表示8位的Unicode字符(UTF-8)。
  4. char16_t :用于表示16位的Unicode字符(UTF-16)。
  5. char32_t :用于表示32位的Unicode字符(UTF-32)。

basic_string 实例化出来的4种类型:

string
wstring
u16string
u32string

        string类是basic_string模版类的一个实例,它使用char来实例化basic_string模版类,并使用char_traits和allocator 作为basic_string的默认参数。

一、string类

1、string类是表示字符序列的类。

2、标准的字符串类提供了对此对象的支持,其接口类似于标准字符容器的接口,但是添加了专门用于操作单字节字符字符串的设计特性。

3、string类封装了字符数组,并提供了一系列成员函数来执行字符串的创建、修改、连接、查找、替换等操作。

        string类出现实际上是比STL要早的,后来才分入STL库里面;所以,string一开始设计比较冗余,有很多重复功能的接口;我们没必要记住所有的接口,只需将核心接口记住并熟练使用就好啦;(如果遇到陌生的接口,直接查看文档就好了)。

string类文档

二、string默认成员函数

        2.1、构造函数

先来看一下C++库里面string的构造函数。

1、string();

        这是没有参数的构造函数(也就是默认构造函数),就是在创建string类对象时不需要传参数。

#include<iostream>
#include<string>

using namespace std;
void test()
{
	string s1;
}

int main()
{
	test();
	return 0;
}

2、string(const char* s);

        在创建string类对象时,传字符串(指针/字符数组),进行类对象的初始化。

使用:用字符串来初始化对象。

void test()
{
	string s1; //string();
	string s2("I Love You"); //string(const char* s);
}

3、string(const char* s, size_t n);

        与上面的构造函数不同的时,在传字符串指针的时,多一个参数n。

使用:用字符数组的前n个字符来初始化string类对象。

void test()
{
	string s1; //string();
	string s2("I Love You"); //string(const char* s);
	string s3("I Love You", 6); //string(const char* s, size_t n);
}

可以通过调试来看对象s1,s2,s3的值

4、string(const string& str);

        在创建string类对象,传同为string类类型的对象进行对象的初始化(也就是拷贝构造函数)。

使用:通过同类型的对象来初始化;

void test()
{
	string s1; //string();
	string s2("I Love You"); //string(const char* s);
	string s3("I Love You", 6); //string(const char* s, size_t n);
	string s4(s2); // string(const string& str);
}

5、string(const string& str, size_t pos, size_t len=npos);

        与拷贝构造不同的时,这个构造函数,还需要多传两个参数pos和len;

使用:用str中的第pos个位置后面len个字符进行初始化对象。

void test()
{
	string s1; //string();
	string s2("I Love You"); //string(const char* s);
	string s3("I Love You", 6); //string(const char* s, size_t n);
	string s4(s2); // string(const string& str);
	string s5(s2, 2, 4); //string(const string& str, size_t pos, size_t len=npos);
}

6、string(size_t n, char ch);

        创建string类对象,并将其内容设置成n个ch。

void test()
{
	string s1; //string();
	string s2("I Love You"); //string(const char* s);
	string s3("I Love You", 6); //string(const char* s, size_t n);
	string s4(s2); // string(const string& str);
	string s5(s2, 2, 4); //string(const string& str, size_t pos, size_t len=npos);
	string s6(6, 'H'); //string(size_t n, char ch);
}

7、

        C++文档中最后一个构造函数,涉及到迭代器,这里先不介绍,后面再使用。

        2.2、析构函数

        析构函数没有函数重载,就不过多叙述。

        2.3、赋值运算符重载

1、string& operator= (const string& str);

        使用:这个就是对于两个已经存在的string类类型对象,进行赋值操作。

void test1()
{
	string s1;
	string s2("Hello World");//拷贝构造
	s1 = s2;//赋值运算符重载

}

2、string& operator= (const char* s);

        使用:将一个字符串赋值给一个已经存在的string类类型对象。

void test1()
{
	string s1;
	string s2("Hello World");//拷贝构造
	s1 = s2;//赋值运算符重载

	string s3; 
	s3 = "I Love ";//operator= (const char* s);
}

3、string& operator= (char ch);

        使用:将一个字符赋值给一个已经存在的string类类型对象。

void test1()
{
	string s1;
	string s2("Hello World");//拷贝构造
	s1 = s2;//赋值运算符重载

	string s3; 
	s3 = "I Love ";//operator= (const char* s);

	string s4;
	s4 = 'c';//operator= (char ch);
}

调试看一下赋值结果:

三、string其他成员函数

        3.1、Capacity

这里就看几个常用的(size、lengh、resize、capacity、clear和empty)。

1、size*

        size就是返回string对象中的字符(数据)个数(也就是字符串的长度)。

2、lengh

        lengh和size一样,都是计算string对象中字符串的长度。

3、resize*

        resize是设置string对象中字符串的内容,(如果n要小于size就将字符串数据个数设为n)如果n大于size,(空间不够就扩容)设置size后面的字符内容。如果给了参数c就设置成 c;如果没有给参数c,就默认设置成'\0'。

4、capacity*

        capacity 返回string对象中可用空间的大小(就像动态顺序表中capacity一样)。

5、clear*

        clear是清理string中字符串的内容,让string对象中字符串变为空,并修改对象中size的值。

6、empty*

        empty判断string对象是否为空;为空就返回true,否则返回false。

7、reserve*

        

        reserve是设置string的空间大小,如果传参n比capacity大就扩容;如果小,不一定会缩小容量。

void test2()
{
	string s1("I Love You !!!");
	//size 返回s1中字符串数据个数
	cout << "size = " << s1.size() << endl;
	//lengh 返回s1中字符串长度
	cout << "lengh = " << s1.length() << endl;
	//capacity 返回s1中可用空间大小
	cout << "capacity = " << s1.capacity() << endl;
	//设置s1中数据个数
	s1.resize(10);
	cout << s1 << endl;
	s1.resize(20, 'x');
	cout << s1 << endl;
	//清理s1中字符串内容,使其变成空
	s1.clear();
	cout << s1 << endl;
	//empty 判断s1中字符串是否为空
	cout << s1.empty() << endl;
}

        3.2、Element access 数据访问

        Element access 就是元素访问,(访问字符串中的数据)。

        这里就主要看 operator[] 和at;

        除了这样访问元素,还可以通过迭代器就行访问(下面在迭代器内容进行使用)。

1、operator[]  *

        operator[] 库里面实现了两个,一个用于普通对象的元素访问(可读可写),另一个就用于const修饰的对象的元素访问(只读)。

        有了operator[] 这个运算符重载的函数,我们就可以像访问字符数组那样去通过下标访问string类型对象。

2、at

        at这个函数是传递一个参数pos,获得string对象中字符串下标为pos的字符。(使用起来和operator[]一样)。

void test3()
{
	string s1("Hello world");
	for (int i = 0; i < s1.size(); i++)
	{
		s1[i]++; //普通对象调用char& operator[](size_t pos); 可以进行修改
		cout << s1[i] << " ";
	}
	cout << endl;
	const string s2("Hello World");
	for (int i = 0; i < s2.size(); i++)
	{
		//s2[i]++; //err
		//const修饰的对象调用const char& operator[](size_t pos) cosnt; 不能进行修改
		cout << s2[i] << " ";
	}
	cout << endl << endl;
	string s3("Hello world");
	for (int i = 0; i < s3.size(); i++)
	{
		s3.at(i)++; //普通对象调用char& at(size_t pos); 可以进行修改
		cout << s3.at(i) << " ";
	}
	cout << endl;
	const string s4("Hello World");
	for (int i = 0; i < s4.size(); i++)
	{
		//s4.at[i]++; //err
		//const修饰的对象调用const char& at(size_t pos) cosnt; 不能进行修改
		cout << s4.at(i) << " ";
	}
	cout << endl;

}

        3.3、Modifiers

        Modifiers ,库里面提供了以下这些函数,对string对象中字符串进行设置(修改)

1、operator+=   *

        库里面实现了三个+=运算符重载函数,我们在使用时就可以像内置类型那样+=;

这里可以+=一个string类类型对象、字符串(字符数组)或者一个字符。

void test4()
{
	string s1("hello ");
	string s2("world ");
	s1 += s2;
	cout << s1 << endl;
	
	char str[] = "ever";
	s1 += str;
	cout << s1 << endl;

	s1 += 'o';
	s1 += 'n';
	s1 += 'e';
	cout << s1 << endl;
}

2、append

        库里面实现的append感觉有点冗余;

        append可以增加string类型对象(也可以是其中的一部分)、字符串(可以是其中的一部分)、n个字符;传参也可以是迭代器。

void test5()
{
	string s1("hello ");
	string s2("world ");
	//s1.append(s2); 也可以直接添加s2的全部
	s1.append(s2, 1, 3);
	//从下标为1的位置开始,添加后面3个字符
	cout << s1 << endl;

	s1.append("everone");
	//s1.append("everone",4);
	//也可以这样,只添加前4个字符
	cout << s1 << endl;

	s1.append(3, 'x');
	//添加3个字符 'x'
	cout << s1 << endl;
}

3、push_back

push_back就是在string对象后面添加一个字符。(比较简单就不测试了)。

4、assgin

        assgin是设置string类对象的内容,(可以用同类型对象来设置(也可以是一部分)、也可以用字符串设置(或者其中一部分)、也可以将strng对象内容设置成n个字符;(也可以传迭代器))。

void test5()
{
	string s1("hello ");
	string s2("world ");
	//s1.append(s2); 
	s1.assign(s2, 1, 3);
	cout << s1 << endl;

	s1.assign("everone");
	//s1.append("everone",4);
	cout << s1 << endl;

	s1.assign(3, 'x');
	cout << s1 << endl;
}

5、insert

        insert与assgin不同,要比assgin多一个参数,这个参数pos就决定了从string对象中字符串哪个位置开始设置字符串的内容。

void test5()
{
	string s1("hello ");
	string s2("world ");
	//s1.append(s2); 
	s1.insert(3, s2, 1, 3);
	cout << s1 << endl;

	s1.insert(8, "everone");
	//s1.append("everone",4);
	cout << s1 << endl;

	s1.insert(15, 3, 'x');
	cout << s1 << endl;
}

6、erase

        erase是删除string对象中字符串的数据,(删除pos位置后面的len和字符);如果不传参就是全部删除(如果只是不传len的参数,就默认删除pos后面所有的数据)。

void test6()
{
	string s1("hello world !!!");
	cout << s1 << endl;
	s1.erase(11, 3);
	cout << s1 << endl;
	s1.erase(5);
	cout << s1 << endl;
	s1.erase();
	cout << s1 << endl;
}

7、replace

replace 替换string对象字符串中的数据;

函数的前两个参数,就是指需要替换的位置(pos位置后面的len个字符)。

        可以替换成string类类型对象(也可以是一部分)、字符串(也可以是一部分)、n个字符或者迭代器指向的区间。

void test7()
{
	string s1("Hello World ");
	string s2("everone");
	cout << s1 << endl;
	s1.replace(6, 5, s2);
	cout << s1 << endl;

	s1.replace(6, 5, "I Love");
	cout << s1 << endl;

	s1.replace(6, 5, 3, '*');
	cout << s1 << endl;
}

8、swap

        swap是库里面实现的一个函数(交换两个string类类型对象)。

void test8()
{
	string s1("hello world");
	string s2("I Love you");
	cout << "s1: " << s1 << endl;
	cout << "s2: " << s2 << endl;
	s1.swap(s2);
	cout << "s1: " << s1 << endl;
	cout << "s2: " << s2 << endl;
}

        3.4、String operations 字符串操作

        字符串操作,主要操作有返回字符串指针、查找、拷贝、获得子串等。(这里就使用其中的一部分)。

1、c_str   *

        c_str返回string对象里的字符串指针。(需要注意的就是返回的指针是const修饰的,必须用const指针接受)。

void test9()
{
	string s1("Hello World");
	const char* s = s1.c_str();
	cout << s << endl;
}

2、find   *

        find查找, 在string对象里查找指定字符(string类类型对象、字符串、字符),也可以指定区间进行查找。找到就返回下标;没有找到返回npos。

void test9()
{
	string s1("Hello World");
	string s2("Hello");
	size_t f1 = s1.find(s2);
	size_t f2 = s1.find("Love");
	size_t f3 = s1.find('o');

	cout << f1 << endl;
	cout << f2 << endl;
	cout << f3 << endl;
}

3、substr   *

        substr获得string对象字符串中的子串。这结合上面的find,

实现将一个网址的协议、域名以及资源分开。

void test10()
{
	string s1("https://blog.csdn.net/LH__1314?type=blog");
	size_t f1 = s1.find("://", 0);
	string protocol = s1.substr(0, f1);

	size_t f2, f3;
	f2 = s1.find('/', f1 + 3);
	string domain = s1.substr(f1 + 3, f2 - (f1 + 3));
	string resource = s1.substr(f2 + 1);

	cout << protocol.c_str() << endl;
	cout << domain.c_str() << endl;
	cout << resource.c_str() << endl;
}

        3.5、Inerator

        inerator就是所谓的迭代器,在string中迭代器作用没有那么大,(甚至可以将它理解为指针(但迭代器不是指针))。

在使用这些函数之前,要先知道一种类型,迭代器 iterator

string::iterator it;

因为在其他容器里也存在迭代器,所以定义时要指定类域。

1、begin、end

        这里的两个函数返回的都是迭代器,begin返回的是起始位置,end返回的是终止位置。

        这里库里面还实现了const修饰的函数,const修饰的迭代器类型有所不同

string::const_iterator it;

这里直接使用:

void test11()
{
	string s1("I Love You");
	string::iterator it = s1.begin();
	while (it != s1.end())
	{
		cout << *it << " ";
		it++;
	}
	cout << endl;
}

2、范围for

有了迭代器,我们就可以实现一种语法 范围for

void test11()
{
	string s1("I Love You");
	for (auto ch : s1)
	{
		cout << ch << " ";
	}
}

到这里,string类的基本使用就结束了。

感谢各位大佬支持并指出问题,

                        如果本篇内容对你有帮助,可以一键三连支持以下,感谢支持!!!

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

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

相关文章

揭开谜底:用 C 语言打造你的扫雷游戏!

目录 1. 功能概述 用户界面 2. 游戏分析与设计 2.1 数据结构分析 地雷存储&#xff1a; 玩家视图&#xff1a; 2.2 文件结构设计 3. 代码实现 game.h game.c test.c 亮点功能与创新 智慧的较量&#xff1a;核心游戏循环 进阶功能&#xff1a;让游戏更加与众不同 还…

MutationObserver详解+案例——深入理解 JavaScript 中的 MutationObserver:原理与实战案例

目录 深入理解 JavaScript 中的 MutationObserver&#xff1a;原理与实战案例 一、MutationObserver 简介 二、MutationObserver 的工作原理 1、基本用法 2、observe 方法的配置项 三、实战案例 案例 1&#xff1a;监控动态内容加载 案例 2&#xff1a;监控属性变化 案…

如何处理模型API速率限制

引言 当我们访问大模型相关的API服务时&#xff0c;通常会遇到速率限制(即限流)&#xff0c;它用于防止用户向某个API发送大量请求&#xff0c;防止请求过载&#xff0c;确保每个人都能公平地访问API。 速率限制的方式 速率限制通常有以下几种形式&#xff1a; RPM(request…

连续时间,离散频率 傅里叶

时域周期——不是把一个信号周期化&#xff0c;而是周期信号取一个周期是x(t),对其周期化不会发生时域的重叠。故当接收到信号&#xff0c;在DFT时&#xff0c;以整个接收到的时间信号为周期进行延拓 推导公式时思路&#xff1a;时域卷积周期冲击&#xff0c;用傅里叶变换推导出…

一键智能改写文章,快速提升内容的吸引力

在这个信息如潮水般涌来的时代&#xff0c;优质的内容创作成为了吸引眼球、传递价值的关键。而有时候&#xff0c;我们可能会面临着已有文章需要优化、旧内容需要焕发新活力的情况。此时&#xff0c;一键智能改写文章的工具就如同一位神奇的魔法师&#xff0c;它能帮助我们将文…

基于深度学习的图像分类或识别系统(含全套项目+PyQt5界面)

目录 一、项目界面 二、代码实现 1、网络代码 2、训练代码 3、评估代码 4、结果显示 三、项目代码 一、项目界面 二、代码实现 1、网络代码 该网络基于残差模型修改 import torch import torch.nn as nn import torchvision.models as modelsclass resnet18(nn.Modul…

【C语言】(指针系列2)指针运算+指针与数组的关系+二级指针+指针数组+《剑指offer面试题》

前言&#xff1a;开始之前先感谢一位大佬&#xff0c;清风~徐~来-CSDN博客&#xff0c;由于是时间久远&#xff0c;博主指针的系列忘的差不多了&#xff0c;所以有些部分借鉴了该播主的&#xff0c;有些地方如果解释的不到位&#xff0c;请翻看这位大佬的&#xff0c;感谢大家&…

C++ char*和char[] 可能指向的内存区域详解(附实验)

C char* 指向的内存区域详解 写在前面c内存结构简介指针常量和常量指针简介情况一&#xff1a;char* 指向栈区内容情况二&#xff1a;char* 指向堆区内容情况三&#xff1a;char* 指向常量区内容情况四&#xff1a;char* 指向静态区内容情况五&#xff1a;char* 指向全局区内容…

Scratch游戏-史诗忍者7免费下载

小虎鲸Scratch资源站-免费少儿编程Scratch作品源码,素材,教程分享网站! 作品描述&#xff1a; 在Scratch版本的《史诗忍者7》中&#xff0c;你需要穿越关卡&#xff0c;击败敌人并收集33个水果。通过灵活的操作和精准的攻击&#xff0c;逐步闯过重重难关。游戏中提供了丰富的技…

【GESP】C++一级练习BCQM3005,基本输出语句printf

一道基础练习题&#xff0c;练习基本输出语句printf。 BCQM3005 题目要求 描述 输出表达式1234∗5678的结果。 输入 无 输出 1234∗56787006652 输入样例 无 输出样例 1234 * 5678 7006652 全文详见个人独立博客&#xff1a;https://www.coderli.com/gesp-1-bcqm3005/ 【…

使用 SuperCraft AI 设计书橱模型的指南

在现代家居设计中&#xff0c;书橱不仅是存放书籍的地方&#xff0c;更是展示个人品味和风格的重要家具。借助 SuperCraft AI&#xff0c;你可以轻松设计出独一无二的书橱。以下是详细的步骤指南&#xff0c;帮助你从零开始设计一个理想的书橱。 1. 创建项目 首先&#xff0c…

【探索数据结构与算法】插入排序:原理、实现与分析(图文详解)

目录 一、插入排序 算法思想 二、插入排序 算法步骤 四、复杂度分析 时间复杂度&#xff1a;O(n^2) 空间复杂度&#xff1a;O(1) 稳定性&#xff1a;稳定算法 五、应用场景 &#x1f493; 博客主页&#xff1a;C-SDN花园GGbond ⏩ 文章专栏&#xff1a;探索数据结构…

node卸载流程

步骤&#xff1a; 1.开始中搜素”命令提示符“&#xff0c;并将其以”管理员身份运行“ 在弹出的框中输入cmd&#xff0c;并确认进入”命令提示符“ 2.在里面通过npm config list查看node相关文件路径&#xff0c; 并找到config from与prefix &#xff0c;后面对应的路径&…

element-plus的菜单组件el-menu

菜单是几乎是每个管理系统的软件系统中不可或缺的&#xff0c;element-plus提供的菜单组件可以快速完成大部分的菜单的需求开发&#xff0c; 该组件内置和vue-router的集成&#xff0c;使用起来很方便。 主要组件如下 el-menu 顶级菜单组件 主要属性 mode:决定菜单的展示模式…

visual studio给项目增加eigen库 手把手教程

Eigen是一个开源的C库&#xff0c;主要用来支持线性代数&#xff0c;矩阵和矢量运算&#xff0c;数值分析及其相关的算法。Eigen 除了C标准库以外&#xff0c;不需要任何其他的依赖包。Eigen库3.4.0版本的下载地址为&#xff1a; https://gitlab.com/libeigen/eigen/-/archive/…

qt-creator-10.0.2之后版本的jom.exe编译速度慢下来了

1、Qt的IDE一直在升级&#xff0c;qt-creator的新版本下载地址 https://download.qt.io/official_releases/qtcreator/ 2、本人一直用的是qt-creator-10.0.2版本&#xff0c;官网历史仓库可以下载安装包qt-creator-opensource-windows-x86_64-10.0.2.exe https://download.qt…

清华大佬自曝:接到了省烟草局的offer,我就拒掉了华为!结果华为立马给我申请了特殊涨薪,总包70w是烟草的2倍,这可如何是好?

《网安面试指南》http://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247484339&idx1&sn356300f169de74e7a778b04bfbbbd0ab&chksmc0e47aeff793f3f9a5f7abcfa57695e8944e52bca2de2c7a3eb1aecb3c1e6b9cb6abe509d51f&scene21#wechat_redirect 《Java代码审…

Java设计模式—面向对象设计原则(四) ----->接口隔离原则(ISP) (完整详解,附有代码+案例)

文章目录 3.4 接口隔离原则(ISP)3.4.1 概述3.4.2 案列 3.4 接口隔离原则(ISP) 接口隔离原则&#xff1a;Interface Segregation Principle&#xff0c;简称ISP 3.4.1 概述 客户端测试类不应该被迫依赖于它不使用的方法&#xff1b;一个类对另一个类的依赖应该建立在最小的接…

我国常见电压等级有哪些?来试试电压版2048让你轻松牢记

作为电气工程专业的小姜同学&#xff0c;平时喜欢敲点代码&#xff0c;前一阵做了一个电气特色的2048小游戏。既能缓解学习压力&#xff0c;又能让大家在玩之中把我国的电压等级牢记于心。 项目预览 功能描述 游戏方法与2048相同&#xff0c;根据我国标准的电压等级&#xff…

基于SpringBoot的人事管理系统【附源码】

基于SpringBoot的人事管理系统&#xff08;源码L文说明文档&#xff09; 目录 4 系统设计 4.1 系统概述 4.2系统功能结构设计 4.3数据库设计 4.3.1数据库E-R图设计 4.3.2 数据库表结构设计 5 系统实现 5.1管理员功能介绍 5.1.1管理员登…