C++ string类(2)—成员访问、插入、删除、替换、查找和交换操作

这篇具有很好参考价值的文章主要介绍了C++ string类(2)—成员访问、插入、删除、替换、查找和交换操作。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一、成员访问

1、operator[ ]&at

2、front( )&back( )

二、插入元素 insert( )

三、删除元素 erase( )

四、替换元素 replace( )

五、查找元素 find( )

六、交换字符串 swap( )

七、C风格 c_str

八、rfind&substr


一、成员访问

1、operator[ ]&at

C++ string类(2)—成员访问、插入、删除、替换、查找和交换操作,C++,c++,开发语言

虽然二者功能一样,但[ ]比较常用。

int main()
{
	string s1("hello world");

	cout << s1[4] << endl;
	cout << s1.at(4) << endl;

	return 0;
}

C++ string类(2)—成员访问、插入、删除、替换、查找和交换操作,C++,c++,开发语言

访问越界[ ]会直接报错,.at( )会抛异常。

int main()
{
	string s1("hello world");

	try {
		s1.at(100);
	}
	catch (const exception& e) {
		cout << e.what() << endl;
	}

	return 0;
}

C++ string类(2)—成员访问、插入、删除、替换、查找和交换操作,C++,c++,开发语言

2、front( )&back( )

C++ string类(2)—成员访问、插入、删除、替换、查找和交换操作,C++,c++,开发语言

int main()
{
	string s1("hello world");

	cout << s1.back() << endl;
	cout << s1.front() << endl;

	return 0;
}

C++ string类(2)—成员访问、插入、删除、替换、查找和交换操作,C++,c++,开发语言

二、插入元素 insert( )

insert/erase不推荐经常使用,能少用就少用,因为他们可能都存在要挪动数据,效率低下。

C++ string类(2)—成员访问、插入、删除、替换、查找和交换操作,C++,c++,开发语言

指定位置插入字符串。

int main()
{
	string s1("world");
	s1.insert(0, "hello");
	cout << s1 << endl;

	return 0;
}

C++ string类(2)—成员访问、插入、删除、替换、查找和交换操作,C++,c++,开发语言

指定位置插入单个字符 

s1.insert(0, "w");

 C++ string类(2)—成员访问、插入、删除、替换、查找和交换操作,C++,c++,开发语言

 两种方式指定位置插入空字符

使用单引号需要加上插入字符个数(第二个参数),使用双引号不需要。

int main()
{
	string s1("world");

	s1.insert(2, 1, ' ');
	s1.insert(3, " ");
	cout << s1 << endl;

	return 0;
}

C++ string类(2)—成员访问、插入、删除、替换、查找和交换操作,C++,c++,开发语言 

 插入可以借助迭代器的begin()和end()获取位置。

s1.insert(s1.begin()+2, ' ');
s1.insert(s1.end() - 1, ' ');

C++ string类(2)—成员访问、插入、删除、替换、查找和交换操作,C++,c++,开发语言 

三、删除元素 erase( )

 insert/erase不推荐经常使用,能少用就少用,因为他们可能都存在要挪动数据,效率低下。 

C++ string类(2)—成员访问、插入、删除、替换、查找和交换操作,C++,c++,开发语言

删除指定位置指定长度字符。 

int main()
{
	string s2("hello world");
	s2.erase(5, 1);
	cout << s2 << endl;

	return 0;
}

C++ string类(2)—成员访问、插入、删除、替换、查找和交换操作,C++,c++,开发语言

也可以使用迭代器。 

    s2.erase(s2.begin() + 5);

 C++ string类(2)—成员访问、插入、删除、替换、查找和交换操作,C++,c++,开发语言

 如果长度大于字符串长度或者缺省,则删除指定位置开始一直到最后的字符。

	s2.erase(5, 30);
    s2.erase(5);

C++ string类(2)—成员访问、插入、删除、替换、查找和交换操作,C++,c++,开发语言 

四、替换元素 replace( )

replace()函数的第一个参数是替换的起始位置,第二个参数是要替换的字符数,第三个参数是替换的字符串。 

int main()
{
	string s1("hello world");
	s1.replace(5, 1, "&&&&");
	cout << s1 << endl;

	return 0;
}
  • 首先,代码中的第一行是被注释掉的,表示字符串s1被初始化为"hello world"。这是一个注释行,不会被执行。
  • 然后,使用s1.replace(5, 1, "&&&&")函数调用来替换字符串s1中从索引位置5开始的1个字符,将其替换为"&&&&"。
  • 接下来,使用cout对象和<<运算符将修改后的字符串s1输出到标准输出流。

C++ string类(2)—成员访问、插入、删除、替换、查找和交换操作,C++,c++,开发语言

使用replace时,空间不够扩容,还要移动数据。 

五、查找元素 find( )

find()用于在字符串中查找指定子串的第一个出现位置。

C++ string类(2)—成员访问、插入、删除、替换、查找和交换操作,C++,c++,开发语言

find()函数有多个重载版本,其中最常用的版本接受一个参数,即要查找的子串。它返回一个整数值,表示子串在字符串中的位置索引。如果找到了子串,则返回第一个匹配的位置索引;如果未找到子串,则返回一个特殊的值std::string::npos

int main()
{
	string s1("hello world I love you");
	size_t pos = s1.find(' ');
	while (pos != string::npos) {
		s1.replace(pos, 1, "***");
		pos = s1.find(' ');
	}
	cout << s1 << endl;
	return 0;
}

C++ string类(2)—成员访问、插入、删除、替换、查找和交换操作,C++,c++,开发语言

我们可以对上述程序进行优化。

int main()
{
	string s1("hello world I love you");
	size_t num = 0;
	for (auto ch : s1) {
		if (ch == ' ')
			++num;
	}
	s1.reserve(s1.size() + 2 * num);
	size_t pos = s1.find(' ');
	while (pos != string::npos) {
		s1.replace(pos, 1, "***");
		pos = s1.find(' ',pos+3);
	}
	cout << s1 << endl;
	return 0;
}
  • 首先,在代码中创建了一个名为s1的字符串对象,并将其初始化为"hello world I love you"。
  • 然后,使用一个循环遍历字符串s1中的每个字符。在循环中,如果当前字符是空格,则将计数器num加1。
  • 接下来,使用s1.reserve(s1.size() + 2 * num)函数调整字符串s1的容量,以便能够容纳替换后的字符串。这样做是为了避免在替换过程中频繁地重新分配内存,提高性能
  • 然后,使用s1.find(' ', pos)函数来查找字符串s1中下一个空格的位置。如果找到了空格,将其位置存储在变量pos中。
  • 接下来,使用s1.replace(pos, 1, "***")函数将找到的空格替换为三个星号"***"。这样做会修改字符串s1中的内容。
  • 然后,使用pos = s1.find(' ', pos + 3)来查找下一个空格的位置,从上一个空格的位置加3开始查找。这样做是为了避免重复替换已经被替换过的空格
  • 循环会一直执行,直到没有更多的空格被找到。
  • 最后,使用cout对象和<<运算符将修改后的字符串s1输出到标准输出流。

 还可以使用+=运算符进一步优化。

int main()
{
	string s1("hello world I love you");
	string newStr;
	size_t num = 0;
	for (auto ch : s1) {
		if (ch != ' ')
			++num;
	}
	newStr.reserve(s1.size() + 2 * num);
	for (auto ch : s1) {
		if (ch != ' ')
			newStr += ch;
		else
			newStr += "***";
	}
	s1 = newStr;
}

与之前的版本相比,这段程序是对第一段程序的改进版本,具有以下特点和优点: 

  1. 更简洁:第二段程序使用了更简洁的方法来替换字符串中的空格,避免了使用循环和查找函数。

  2. 更高效:第二段程序只需遍历一次原始字符串,而不是使用循环和查找函数多次遍历。这样可以减少时间复杂度,提高程序的执行效率。

  3. 更易读:第二段程序使用了更直观的方式来替换空格,通过判断字符是否为空格来决定添加字符还是添加"***"。这样代码更易读懂,减少了冗余的操作。

  4. 更节省内存:第二段程序使用了新的字符串newStr来存储替换后的结果,避免了对原始字符串s1进行频繁的修改。这样可以减少内存的使用,提高程序的效率。

六、交换字符串 swap( )

int main()
{
	string s1("hello world");
	string s2("xxxxx");
	s1.swap(s2);
	cout << s1 << endl;
	cout << s2 << endl;

	swap(s1, s2);
	cout << s1 << endl;
	cout << s2 << endl;
}

C++ string类(2)—成员访问、插入、删除、替换、查找和交换操作,C++,c++,开发语言

这段程序中的两个swap函数调用有以下区别:

  1. std::string::swapstd::string类的成员函数,它直接在两个字符串对象之间交换数据,通常是通过交换内部指针来实现的,所以它的效率非常高,几乎是常数时间复杂度。

  2. std::swap是标准库提供的一个模板函数,它可以用于交换任何类型的两个对象。对于std::string类型,std::swap内部实际上也是调用的std::string::swap,所以效率也是很高的。

总的来说,这两种方法在效率上是相当的,你可以根据实际情况和编程风格来选择使用哪一种。如果代码只涉及到字符串交换,那么使用std::string::swap可能会更直观一些;如果代码需要处理多种类型的交换,那么使用std::swap可能会更通用一些

七、C风格 c_str

int main()
{
	string s1("hello world");
	cout << s1 << endl;
	cout << s1.c_str() << endl;

	return 0;
}
  1. cout << s1 << endl;:这行代码将字符串对象s1直接输出到标准输出流cout中。它会输出s1的内容,即字符串 "hello world"。

  2. cout << s1.c_str() << endl;:这行代码使用了字符串对象s1c_str()成员函数。c_str()函数返回一个指向以空字符结尾的字符数组(C风格字符串)的指针。然后,该指针被传递给cout输出流进行输出。它也会输出s1的内容,即字符串 "hello world"。

区别在于输出的方式不同。第一行直接输出字符串对象s1的内容,而第二行使用了c_str()函数将字符串对象转换为C风格字符串后输出。通常情况下,直接输出字符串对象更为简洁和方便。

int main()
{
	string s1("hello world");
    cout << s1 << endl;
	cout << s1.c_str() << endl;
	s1 += '\0';
	s1 += '\0';
	s1 += "xxxxx";
	cout << s1 << endl;
	cout << s1.c_str() << endl;

	return 0;
}

可以看到,通过对s1进行修改操作后,输出结果中的空字符('\0')在字符串对象s1的输出中仍然存在,但在c_str()函数返回的C风格字符串中被忽略了。这是因为c_str()函数会将字符串以空字符结尾,而在输出时遇到空字符就会停止输出。 

C++ string类(2)—成员访问、插入、删除、替换、查找和交换操作,C++,c++,开发语言

我们逐步解释为什么输出结果会有所不同。

初始状态下,s1的值为"hello world"。

  1. cout << s1 << endl;:输出s1的内容,即字符串 "hello world"。

  2. cout << s1.c_str() << endl;:输出s1的C风格字符串表示,即 "hello world"。

  3. s1 += '\0';:在s1末尾添加一个空字符('\0'),此时s1的值变为 "hello world\0"。

  4. s1 += '\0';:再次在s1末尾添加一个空字符('\0'),此时s1的值变为 "hello world\0\0"。

  5. s1 += "xxxxx";:将字符串 "xxxxx" 追加到s1的末尾,此时s1的值变为 "hello world\0\0xxxxx"。

  6. cout << s1 << endl;:输出s1的内容,即 "hello world\0\0xxxxx"。

  7. cout << s1.c_str() << endl;:输出s1的C风格字符串表示,即 "hello world"。这里需要注意,c_str()函数返回的是以空字符结尾的字符数组,输出时遇到第一个空字符就会停止输出。

八、rfind&substr

rfind函数用于在一个字符串中从后往前搜索指定的子字符串,并返回子字符串的位置。

它的语法如下:

size_t rfind(const string& str, size_t pos = string::npos) const;

str是要搜索的子字符串,pos是搜索的起始位置,默认为string::npos,表示从字符串的末尾开始搜索。

substr函数用于从一个字符串中提取子字符串。它的语法如下:

string substr(size_t pos = 0, size_t len = string::npos) const;

其中,pos是要提取的子字符串的起始位置,默认为0,len是要提取的子字符串的长度,默认为string::npos,表示提取从起始位置到字符串末尾的所有字符。

接下来看下面代码:

int main()
{
	string file("string.cpp.tar.zip");
	size_t pos = file.rfind('.');
	if (pos != string::npos)
	{
		string suffix = file.substr(pos);
		cout << suffix << endl;
	}

	return 0;
}

C++ string类(2)—成员访问、插入、删除、替换、查找和交换操作,C++,c++,开发语言

这段代码的目的是提取文件名中的后缀名。

  • 首先,定义了一个字符串file,其中包含了一个文件名string.cpp.tar.zip
  • 然后,使用rfind函数从后往前搜索.字符的位置,并将结果保存在变量pos中。如果找到了.字符,则pos的值不等于string::npos
  • 接下来,通过判断pos的值是否不等于string::npos,来确定是否找到了.字符。如果找到了,则使用substr函数从pos位置开始提取子字符串,并将结果保存在变量suffix中。
  • 最后,将提取到的后缀名输出到标准输出流cout中,然后换行。

在这个例子中,输出结果为.zip,因为.字符后面的部分就是文件的后缀名。

 从URL中提取主机地址:

int main()
{
	string url("http://www.cplusplus.com/reference/string/string/find/");
	cout << url << endl;
	size_t start = url.find("://");
	if (start == string::npos)
	{
		cout << "invalid url" << endl;
	}

	start += 3;
	size_t finish = url.find('/', start);
	string address = url.substr(start, finish - start);
	cout << address << endl;


	return 0;
}

C++ string类(2)—成员访问、插入、删除、替换、查找和交换操作,C++,c++,开发语言

使用find函数搜索字符串url中第一次出现的子字符串"://"的位置,并将结果保存在变量start中。如果找不到该子字符串,则start的值等于string::npos

接下来,通过判断start的值是否等于string::npos,来确定是否找到了"://"子字符串。如果没有找到,则输出"invalid url",表示URL无效。

如果找到了"://"子字符串,则将start的值增加3,以跳过"://"部分,然后使用find函数搜索从start位置开始的下一个'/'字符的位置,并将结果保存在变量finish中。

最后,使用substr函数从start位置开始,提取从startfinish之间的子字符串,并将结果保存在变量address中,将提取到的主机地址输出到标准输出流cout中,然后换行。文章来源地址https://www.toymoban.com/news/detail-753699.html

到了这里,关于C++ string类(2)—成员访问、插入、删除、替换、查找和交换操作的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【数据结构】18 二叉搜索树(查找,插入,删除)

    二叉搜索树也叫二叉排序树或者二叉查找树。它是一种对排序和查找都很有用的特殊二叉树。 一个二叉搜索树可以为空,如果它不为空,它将满足以下性质: 非空左子树的所有键值小于其根节点的键值 非空右子树的所有键值都大于其根结点的键值 左、右子树都是二叉树 在

    2024年02月22日
    浏览(49)
  • 【数据结构】单链表基本操作:查找、插入、删除、创建

     链表由结点组成,结点由数据域和指针域组成。其中,数据域存放的就是数据元素,指针域存放下一个结点的地址。数据元素可以只有一个,也可以有多个不同类型的数据元素,甚至是数组。下图和代码来自《C Primer Plus》,该链表每个节结点同时含char类型和int类型。 ​​

    2024年02月02日
    浏览(64)
  • 数据结构--6.5二叉排序树(插入,查找和删除)

    目录 一、创建  二、插入 三、删除   二叉排序树(Binary Sort Tree)又称为二叉查找树,它或者是一棵空树,或者是具有下列性质的二叉树: ——若它的左子树不为空,则左子树上所有结点的值均小于它的根结构的值; ——若它的右子树不为空,则右子树上所有结点的值均大

    2024年02月09日
    浏览(33)
  • 二叉搜索树(查找、插入、删除的讲解实现+图文并茂)

    目录 1. 二叉搜索树(BST)   1.1 二叉搜索树概念   1.2 二叉搜索树操作         1.2.1 二叉搜索树的查找         1.2.2 二叉搜索树的插入          1.2.3 二叉搜索树的删除 2. 二叉搜索树的实现   2.1BST基本结构   2.2 BST操作成员函数(非递归)   2.3 BST操作成员函数(递归) 3. 二

    2024年02月06日
    浏览(61)
  • 单链表上基本操作的实现——建立,插入,查找,删除,表长。

    提示,可以根据目录,可以从 单链表的插入 删除——单链表的查找——单链表的建立 这样的顺序进行学习!!! 单链表的建立主要包括两种建立方法: 头插法 与 尾插法 。 基本步骤如下: 初始化一个单链表 每次取一个数据元素,* 插入到表尾/表头 *(导致于头插法,尾插

    2023年04月09日
    浏览(41)
  • 顺序表创建,初始化,赋值,取值,查找,插入与删除(附小例题)

    由n(n≥0)个数据结构相同的元素构成的有限序列。 1)除了第一个元素外,结构中的每一个数据元素均只有一个前驱 2)除了最后一个元素外,结构中的每一个数据元素均只有一个后驱 用一组地址 连续的存储单元依次 存储线性表的数据元素。 优点 : 随机存储 缺点 :在做插

    2024年02月07日
    浏览(44)
  • 二叉排序树的创建、插入、查找和删除【数据结构】

    若它的左子树不空,则左子树上所有结点的值均小于它根结点的值。 若它的右子树不空,则右子树上所有结点的值均大于它根结点的值。 它的左、右树又分为⼆叉排序树 二叉排序树也叫二叉查找树、二叉搜索树 题目描述 给出一个数据序列,建立二叉排序树,并实现插入功

    2024年01月24日
    浏览(44)
  • B树 B+树(多路查找树)的介绍、插入和删除操作

    是一类特殊的树形结构,其每个节点可以包含多个和对应的指针,相比于二叉查找树,可以更高效地进行查找操作。 B树和B+树 其中B树是一种自平衡的多路查找树,其每个节点可以包含多个和对应的指针,且满足以下性质:多路查找树是一类特殊的树形结构,其

    2023年04月18日
    浏览(36)
  • 链表基础知识(一、单链表、头插、尾插、头删、尾删、查找、删除、插入)

    目录 一、链表表示和实现 1.1 链表的概念及结构  二、链表的分类: 2.1实际中要实现的链表的结构非常多样,以下情况组合起来就有8种链表结构:  2.2链表和顺序表的对比 三、单链表 3.1无头+单向+非循环链表增删查改实现 3.2SList.h  3.3打印链表 3.4新建一个节点 3.5尾插 3.6头

    2024年02月04日
    浏览(40)
  • C++:替换string中的字符

    1.按照位置进行替换 string的成员函数replace可以满足这种需求,其变体有很多种,请参考官方文档,以下列举常用的两种: 运行程序输出: hi world hello world 2.替换指定的字符 如果需要将string中所有指定的字符全部替换,如果使用成员函数replace比较的麻烦,这时可以使用STL的

    2024年02月13日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包