C++:string 类详解

news2024/9/19 23:36:41

目录

简介

使用

初始化(构造函数、拷贝构造函数)

析构函数

赋值运算符重载(operator=)

成员常量(npos)

运算符重载[ ](operator[ ])

size() 和 length()

迭代器( begin() 和 end() )

范围 for 

迭代器和范围 for 的比较

反向迭代器( rbegin() 和 rend() )

const 迭代器(正向、反向)

max_size()

capacity()

reserve()

clear()

empty()

shrink_to_fit()

resize()

at()

运算符重载( operator += )

append() 和 push_back()

insert()

erase()

replace()

swap()

find()

rfind()

find_first_of() 和 find_last_of()

find_first_not_of() 和 find_last_not_of()

substr()

getline()

运算符重载( operator + )

运算符重载一系列比较大小的函数(relational operators (string) - C++ Reference)

完整代码


简介

C++的 string 类是一个功能强大的字符串处理类,其通过实现多个构造函数的重载,允许用户以多种方式创建字符串对象,并提供了多种操作字符串的方法,包括定义、插入、拼接、删除、查找、比较、替换、交换、访问元素、使用运算符、与迭代器相关的函数、与字符串之间的转换、提取子字符串等一系列操作。

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

使用

要使用 string 类,就要包含相应的头文件( #include<string> ),还要注意一点,string 类也是写在 std 这个命名空间中的,如果不想每次都要写是哪个命名空间的,就必须包含using namespace std。

先来看string类的默认成员函数。

初始化(构造函数、拷贝构造函数)

string类的初始化,也就是使用其构造函数和拷贝构造,由于C++支持函数重载,故可以看到string类重载了多个不同功能的函数。

使用方法:

先来看重载的1、2、4这三个:

void test()
{
	//无参构造
	string s1;
	//带参构造
	string s2("hello world");
	//拷贝构造函数
	string s3(s2);

	cout << s1 << endl;
	cout << s2 << endl;
	cout << s3 << endl;
}

由于 string 类重载了流插入和流提取,我们可以直接使用它来输出字符串。

重载的第三个与第二个相比,多了两个参数,其功能为从第 pos 位置开始拷贝要拷贝对象的前 len  个字符,如果未指定(或者要拷贝的长度大于剩余字符串的长度),默认拷贝到结尾。所以其第二个参数是用来指定位置的,第三个参数是用来指定要拷贝字符的长度的。

void test()
{
	//无参构造
	string s1;
	//带参构造
	string s2("hello world");
	//拷贝构造函数
	string s3(s2);
	//从下标为6的位置开始,拷贝9个字符,如果超过长度,就拷贝到结尾的位置。
	string s4(s2, 6, 9);

	cout << s1 << endl;
	cout << s2 << endl;
	cout << s3 << endl;
	cout << s4 << endl;
}

第五个则是使用字符串的前n个进行初始化。

void test()
{
	//无参构造
	string s1;
	//带参构造
	string s2("hello world");
	//拷贝构造函数
	string s3(s2);
	//从下标为6的位置开始,拷贝9个字符,如果超过长度,就拷贝到结尾的位置。
	string s4(s2, 6, 9);
	//使用字符串的前五个进行初始化
	string s5("HELLO WORLD", 5);

	cout << s1 << endl;
	cout << s2 << endl;
	cout << s3 << endl;
	cout << s4 << endl;
	cout << s5 << endl;
}

第六个则是使用 n 个字符 c 进行初始化。

void test()
{
	//无参构造
	string s1;
	//带参构造
	string s2("hello world");
	//拷贝构造函数
	string s3(s2);
	//从下标为6的位置开始,拷贝9个字符,如果超过长度,就拷贝到结尾的位置。
	string s4(s2, 6, 9);
	//使用字符串的前五个进行初始化
	string s5("HELLO WORLD", 5);
	//使用个'x'进行初始化
	string s6(5, 'x');

	cout << s1 << endl;
	cout << s2 << endl;
	cout << s3 << endl;
	cout << s4 << endl;
	cout << s5 << endl;
	cout << s6 << endl;
}

第七个则是使用了迭代器,这里先不做介绍,后边会详细介绍。

析构函数

析构函数会自动调用,所以不需要过多关注。

赋值运算符重载(operator=)

string 类中也实现了赋值运算符重载。其支持同类型、字符串、字符的赋值。

void test()
{
	//无参构造
	string s1;
	//带参构造
	string s2("hello world");
	//拷贝构造函数
	string s3(s2);
	//从下标为6的位置开始,拷贝9个字符,如果超过长度,就拷贝到结尾的位置。
	string s4(s2, 6, 9);
	//使用字符串的前五个进行初始化
	string s5("HELLO WORLD", 5);
	//使用个'x'进行初始化
	string s6(5, 'x');

	cout << s1 << endl;
	cout << s2 << endl;
	cout << s3 << endl;
	cout << s4 << endl;
	cout << s5 << endl;
	cout << s6 << endl;

	//赋值重载,支持同类型、字符串等的赋值
	s6 = s5;
	cout << s6 << endl;

	s6 = "Hello";
	cout << s6 << endl;

	s6 = 'H';
	cout << s6 << endl;
}

成员常量(npos)

其最大值是一个静态成员常量值,具有size_t类型元素的最大可能值。

在被当用作字符串成员函数中 len 参数的值时,此值表示“直到字符串结束”。

作为返回值,它通常用于表示没有匹配项。

该常数定义为值-1,因为size_t是一个无符号整数类型,所以它是该类型的最大可表示值。

运算符重载[ ](operator[ ])

有了这个,我们可以直接通过下标进行访问和进行修改。其重载了两个,为普通成员和const成员变量。

void test1()
{
	string s("Hello,world");
	cout << s << endl;

	s[5] = ' ';
	cout << s << endl;

	cout << s[0] << endl;
}

const 成员变量不能修改,只能访问。

size() 和 length()

使用 size 可以得到字符串的长度。

void test2()
{
	string s("Hello,world");
	cout << s << endl;

	for (int i = 0; i < s.size(); i++)
	{
		cout << s[i] << ' ';
	}
	cout << endl;
}

size() 与 length() 方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一致,一般情况下基本都是用size()。

除此之外,实现输出每个字符还有另外的方法。

迭代器( begin() 和 end() )

可以使用迭代器来实现遍历输出。begin() 会获取到字符串开始的位置,end() 会取到字符串最后一个字符的下一个位置,也就是会取到 '\0' 的位置。

要使用它们就要先创建一个迭代器对象,其用法类似于指针。

void test2()
{
	string s("Hello,world");
	cout << s << endl;

	for (int i = 0; i < s.size(); i++)
	{
		cout << s[i] << ' ';
	}
	cout << endl;

	//先创建一个迭代器对象获取到开始位置
	string::iterator it = s.begin();
	while (it != s.end())
	{
		cout << *it << ' ';
		it++;
	}
	cout << endl;
}

范围 for 

还可以通过范围 for 来实现。

void test2()
{
	string s("Hello,world");
	cout << s << endl;

	for (int i = 0; i < s.size(); i++)
	{
		cout << s[i] << ' ';
	}
	cout << endl;

	//先创建一个迭代器对象获取到开始位置
	string::iterator it = s.begin();
	while (it != s.end())
	{
		cout << *it << ' ';
		it++;
	}
	cout << endl;

	//范围for
	for (auto i : s)
	{
		cout << i << ' ';
	}
	cout << endl;
}

其会自动赋值,自动迭代,自动判断结束。但其底层仍是迭代器,依旧是用 begin() 和 end()实现出来的。

迭代器和范围 for 的比较

在迭代器中,我们可以通过迭代器对象修改字符串。但范围 for 不行,其只是字符串的一个拷贝,不能修改字符串本身。

void test2()
{
	string s("Hello,world");
	cout << s << endl;

	for (int i = 0; i < s.size(); i++)
	{
		cout << s[i] << ' ';
	}
	cout << endl;

	//先创建一个迭代器对象获取到开始位置
	string::iterator it = s.begin();
	while (it != s.end())
	{
		*it += 1;
		cout << *it << ' ';
		it++;
	}
	cout << endl;
	cout << s << endl;

	//范围for
	for (auto i : s)
	{
		i -= 1;
		cout << i << ' ';
	}
	cout << endl;
	cout << s << endl;
}

但如果给范围 for 加上引用,就可以改变字符串。

反向迭代器( rbegin() 和 rend() )

 前面的迭代器为正向迭代器,其从开始位置进行遍历。所以,反向迭代器就会从结尾位置开始,向前遍历。rbegin() 会获取到字符串结尾字符的位置,rend() 会取到字符串开始位置的前一个位置。

void test3()
{
	string s("Hello,world");
	cout << s << endl;

	//正向迭代器
	string::iterator it = s.begin();
	while (it != s.end())
	{
		cout << *it << ' ';
		it++;
	}
	cout << endl;

	//反向迭代器
	string::reverse_iterator rit = s.rbegin();
	while (rit != s.rend())
	{
		cout << *rit << ' ';
		rit++;
	}
	cout << endl;
}

const 迭代器(正向、反向)

const 的不能进行修改。其也可以分为两个版本,正向和反向的。

void test4()
{
	const string s("Hello,world");
	cout << s << endl;

	//正向迭代器
	string::const_iterator it = s.begin();
	while (it != s.end())
	{
		cout << *it << ' ';
		it++;
	}
	cout << endl;

	//反向迭代器
	string::const_reverse_iterator rit = s.rbegin();
	while (rit != s.rend())
	{
		cout << *rit << ' ';
		rit++;
	}
	cout << endl;
}

此外,C++11又新增加了四个专门供 const 迭代器类型使用的。与原先差别不大,只是将其更准确的表达。

max_size()

其用来返回能存储字符串的最大值。

void test4()
{
	const string s("Hello,world");
	cout << s << endl;
	cout << s.max_size() << endl;
}

capacity()

其用来返回为字符串所开空间的大小。string 类的底层实现类似于顺序表,会动态分配内存。其与size() 不同,所开内存空间的大小一定是等于或大于字符串长度的。

void test5()
{
	const string s("Hello,world");
	cout << s << endl;
	cout << s.max_size() << endl;
	cout << s.size() << endl;
	cout << s.capacity() << endl;
}

reserve()

其常用来扩容,用来请求 n 个字节的长度。如果 n 大于当前容量,其至少会扩容到 n (具体情况要看编译器)。如果 n 小于当前容量,有可能容量不变,或缩至 n ,这要看不同编译器的实现。

void test5()
{
	string s("Hello,world");
	cout << s << endl;
	cout << s.max_size() << endl;
	cout << s.size() << endl;
	cout << s.capacity() << endl;

	s.reserve(100);
	cout << s.size() << endl;
	cout << s.capacity() << endl;

	s.reserve(13);
	cout << s.size() << endl;
	cout << s.capacity() << endl;

	s.reserve(10);
	cout << s.size() << endl;
	cout << s.capacity() << endl;
}

但不管如何,其都不会影响字符串的大小。

clear()

其用来清空数据,但容量大小不变。

void test5()
{
	string s("Hello,world");
	cout << s << endl;
	cout << s.max_size() << endl;
	cout << s.size() << endl;
	cout << s.capacity() << endl;

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

empty()

用来判断字符串是否为空。

void test5()
{
	string s("Hello,world");
	cout << s << endl;
	cout << s.max_size() << endl;
	cout << s.size() << endl;
	cout << s.capacity() << endl;

	s.clear();
	cout << s.size() << endl;
	cout << s.capacity() << endl;

	if (s.empty())
	{
		cout << "字符串为空" << endl;
	}
	else
	{
		cout << "字符串不为空" << endl;
	}
}

shrink_to_fit()

其会请求减小容量以适应字符串的长度。但不会对字符串长度产生影响。

void test5()
{
	string s("Hello,world");
	cout << s << endl;
	cout << s.max_size() << endl;
	cout << s.size() << endl;
	cout << s.capacity() << endl;

	s.reserve(100);
	cout << s.size() << endl;
	cout << s.capacity() << endl;

	s.shrink_to_fit();
	cout << s.size() << endl;
	cout << s.capacity() << endl;
}

resize()

其会改变容量的大小。如果要插入的数据 n 小于字符串长度,其会变为长度为 n 的字符串,如果大于字符串长度,其会填充符号(默认是'\0') 至 n 。如果 n 在大于字符串长度的同时还大于容量,会填充字符并扩容。

void test5()
{
	string s("Hello,world");
	cout << s << endl;
	cout << s.max_size() << endl;
	cout << s.size() << endl;
	cout << s.capacity() << endl;

	s.resize(15);
	cout << s << endl;
	cout << s.size() << endl;
	cout << s.capacity() << endl;

	s.resize(20, 'x');
	cout << s << endl;
	cout << s.size() << endl;
	cout << s.capacity() << endl;

	s.resize(9);
	cout << s << endl;
	cout << s.size() << endl;
	cout << s.capacity() << endl;
}

at()

其与 operator[ ] 的功能相同,区别是当要访问的下标越界时 operator[ ] 会断言报错,而 at() 会抛出异常。

void test6()
{
	string s("hello,world");
	cout << s << endl;
	cout << s.at(0) << endl;
	s.at(0) = 'x';
	cout << s << endl;
}

运算符重载( operator += )

将 += 运算符重载之后,就能实现字符串的拼接。

void test6()
{
	string s("hello,world");
	cout << s << endl;

	s += "!!!!!!";
	cout << s << endl;
}

append() 和 push_back()

其功能也是拼接字符串,但 push_back() 只能拼接单个字符,append() 则被设计出来用来拼接字符串。但其都可以直接使用 operator += 来实现,所以这两个可以简单了解一下使用方法。

void test6()
{
	string s("hello,world");
	cout << s << endl;

	s += "!!!!!!";
	cout << s << endl;

	s.push_back('x');
	cout << s << endl;

	s.append("HELLO");
	cout << s << endl;
}

insert()

其用于在 pos 位置插入字符。

void test6()
{
	string s("hello,world");
	cout << s << endl;

	s += "!!!!!!";
	cout << s << endl;

	s.push_back('x');
	cout << s << endl;

	s.append("HELLO");
	cout << s << endl;

	//插入多个字符
	s.insert(0, "11111");
	cout << s << endl;

	s.insert(6, "w");
	cout << s << endl;

	//插入单个字符
	s.insert(9, 1, 'w');
	cout << s << endl;
}

erase()

用于删除数据。

void test6()
{
	string s("hello,world");
	cout << s << endl;

	s += "!!!!!!";
	cout << s << endl;

	s.push_back('x');
	cout << s << endl;

	s.append("HELLO");
	cout << s << endl;

	//插入多个字符
	s.insert(0, "11111");
	cout << s << endl;

	s.insert(6, "w");
	cout << s << endl;

	//插入单个字符
	s.insert(9, 1, 'w');
	cout << s << endl;

	//删除字符
	s.erase(0, 4);
	cout << s << endl;

	//迭代器用法
	s.erase(s.begin());
	cout << s << endl;
}

其要删除数据如果大于字符串的长度,其默认会删除到字符串结尾。

replace()

其把字符串的一部分替换为另一部分。

void test7()
{
	string s("hello,world");
	cout << s << endl;

	//插入单个字符
	s.replace(5, 1, 1, 'x');
	cout << s << endl;

	//插入多个字符
	s.replace(5, 1, " ");
	cout << s << endl;
}

swap()

用于交换两个字符串的值。

void test7()
{
	string s("hello,world");
	cout << s << endl;

	string s1("aaaaaaa");
	cout << s1 << endl;

	s.swap(s1);
	cout << s << endl;
	cout << s1 << endl;
}

find()

用来查找特定的字符串(从前向后进行查找),如果查找到,就返回第一个查找的该位置下标,若没有,就返回 npos 。

void test7()
{
	string s("hello,world");
	cout << s << endl;

	//插入单个字符
	s.replace(5, 1, 1, 'x');
	cout << s << endl;

	//插入多个字符
	s.replace(5, 1, " ");
	cout << s << endl;

	string s1("aaaaaaa");
	cout << s1 << endl;

	s.swap(s1);
	cout << s << endl;
	cout << s1 << endl;

	size_t pos = s1.find(' ');
	while (pos != string::npos)
	{
		s1.replace(pos, 1, "x");
		pos = s1.find(' ');
	}
	cout << s1 << endl;
}

该函数第二个参数是从 pos 位置开始向后进行查找。其默认为开始位置。

void test7()
{
	string s("hello,world");
	cout << s << endl;

	//插入单个字符
	s.replace(5, 1, 1, 'x');
	cout << s << endl;

	//插入多个字符
	s.replace(5, 1, " ");
	cout << s << endl;

	string s1("aaaaaaa");
	cout << s1 << endl;

	s.swap(s1);
	cout << s << endl;
	cout << s1 << endl;

	size_t pos = s1.find(' ');
	while (pos != string::npos)
	{
		s1.replace(pos, 1, "x");
		pos = s1.find(' ');
	}
	cout << s1 << endl;

	size_t pos1 = s1.find('o', 6);
	while (pos1 != string::npos)
	{
		s1.replace(pos1, 1, "x");
		pos1 = s1.find('o', 6);
	}
	cout << s1 << endl;
}

rfind()

用于查找特定字符(从后向前进行查找),如果找到,就返回最后一个出现该字符的位置。若没有,就返回 npos 。该函数第二个参数是从 pos 位置开始向前进行查找。其默认为结尾位置。

void test7()
{
	string s("hello,world");
	cout << s << endl;

	//插入单个字符
	s.replace(5, 1, 1, 'x');
	cout << s << endl;

	//插入多个字符
	s.replace(5, 1, " ");
	cout << s << endl;

	string s1("aaaaaaa");
	cout << s1 << endl;

	s.swap(s1);
	cout << s << endl;
	cout << s1 << endl;

	size_t pos = s1.find(' ');
	while (pos != string::npos)
	{
		s1.replace(pos, 1, "x");
		pos = s1.find(' ');
	}
	cout << s1 << endl;

	size_t pos1 = s1.find('o', 6);
	while (pos1 != string::npos)
	{
		s1.replace(pos1, 1, "x");
		pos1 = s1.find('o', 6);
	}
	cout << s1 << endl;

	size_t pos2 = s1.rfind('l', 4);
	while (pos2 != string::npos)
	{
		s1.replace(pos2, 1, " ");
		pos2= s1.rfind('l', 4);
	}
	cout << s1 << endl;
}

find_first_of() 和 find_last_of()

其是查找字符串中所指定的多个字符,并返回它们的位置。不同的是,find_first_of() 是从前向后查找,find_last_of() 则是从后向前查找。其第二个参数依旧是指定开始查找的位置。

void test8()
{
	string s("How are you? I'm fine thank you. And you?");
	cout << s << endl;

	//查找并返回包含"AaBbCcDdEe"的所有为字符的位置
	size_t pos = s.find_first_of("AaBbCcDdEe");
	while (pos != string::npos)
	{
		s.replace(pos, 1, "*");
		pos = s.find_first_of("AaBbCcDdEe");
	}
	cout << s << endl;
}

find_last_of() 则是从后向前进行查找,这里不再进行演示。

find_first_not_of() 和 find_last_not_of()

其与 find_first_of() 和 find_last_of() 正好相反,是查找字符串中除所指定的多个字符外的其余字符,并返回它们的位置。不同的是,find_first_not_of() 是从前向后查找,find_last_not_of() 则是从后向前查找。其第二个参数依旧是指定开始查找的位置。

用法与上方相同。

substr()

其用于拷贝字符串。从pos位置开始拷贝 n 个字符,如果未指定 n ,默认会拷贝到结尾。

void test8()
{
	string s("How are you? I'm fine thank you. And you?");
	cout << s << endl;

	//查找并返回包含"AaBbCcDdEe"的所有为字符的位置
	size_t pos = s.find_first_of("AaBbCcDdEe");
	while (pos != string::npos)
	{
		s.replace(pos, 1, "*");
		pos = s.find_first_of("AaBbCcDdEe");
	}
	cout << s << endl;

	string s1 = s.substr(9);
	cout << s1 << endl;

	string s2 = s1.substr(9, 9);
	cout << s2 << endl;
}

getline()

其用于提取输入的字符并存储在字符串中,直至遇到 '\n' ,或自己定义的中止符。

如果遇到将要输入的一段话储存在一个字符串中,那 cin 是无法实现的,而 getline 就是解决这个问题的。

void test9()
{
	string s;
	//cin >> s;
	getline(cin, s);
	cout << s << endl;
}

或者自己指定结束的标志:

void test9()
{
	string s;
	//cin >> s;
	//getline(cin, s);
	getline(cin, s, ',');
	cout << s << endl;
}

运算符重载( operator + )

其支持两个 string 对象相加,支持 string 对象和字符串相加,然后返回一个新的 string 对象。

void test9()
{
	string s("hello,world");
	cout << s << endl;

	string s1 = s + "xxxxx";
	cout << s1 << endl;

	string s2 = s + s1;
	cout << s2 << endl;

	string s3 = "aaaaa" + s2;
	cout << s3 << endl;
}

但不支持两个字符串相加。

运算符重载一系列比较大小的函数(relational operators (string) - C++ Reference)

C++写了重载了一系列有关比较大小的函数,可以直接实现两个string对象的比较,字符串与string对象的比较。但其不支持两个字符串的比较。

完整代码

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

void test()
{
	//无参构造
	string s1;
	//带参构造
	string s2("hello world");
	//拷贝构造函数
	string s3(s2);
	//从下标为6的位置开始,拷贝9个字符,如果超过长度,就拷贝到结尾的位置。
	string s4(s2, 6, 9);
	//使用字符串的前五个进行初始化
	string s5("HELLO WORLD", 5);
	//使用个'x'进行初始化
	string s6(5, 'x');

	cout << s1 << endl;
	cout << s2 << endl;
	cout << s3 << endl;
	cout << s4 << endl;
	cout << s5 << endl;
	cout << s6 << endl;

	//赋值重载,支持同类型、字符串等的赋值
	s6 = s5;
	cout << s6 << endl;

	s6 = "Hello";
	cout << s6 << endl;

	s6 = 'H';
	cout << s6 << endl;
}

void test1()
{
	string s("Hello,world");
	cout << s << endl;

	s[5] = ' ';
	cout << s << endl;

	cout << s[0] << endl;

	const string s1(6, 'x');
	cout << s1[0] << endl;

	//s1[0] = 'H';

	
}

void test2()
{
	string s("Hello,world");
	cout << s << endl;

	for (int i = 0; i < s.size(); i++)
	{
		cout << s[i] << ' ';
	}
	cout << endl;

	//先创建一个迭代器对象获取到开始位置
	string::iterator it = s.begin();
	while (it != s.end())
	{
		*it += 1;
		cout << *it << ' ';
		it++;
	}
	cout << endl;
	cout << s << endl;

	//范围for
	//for (auto i : s)
	for (auto& i : s)
	{
		i -= 1;
		cout << i << ' ';
	}
	cout << endl;
	cout << s << endl;
}

void test3()
{
	string s("Hello,world");
	cout << s << endl;

	//正向迭代器
	string::iterator it = s.begin();
	while (it != s.end())
	{
		cout << *it << ' ';
		it++;
	}
	cout << endl;

	//反向迭代器
	string::reverse_iterator rit = s.rbegin();
	while (rit != s.rend())
	{
		cout << *rit << ' ';
		rit++;
	}
	cout << endl;
}

void test4()
{
	const string s("Hello,world");
	cout << s << endl;
	cout << s.max_size() << endl;

	//正向迭代器
	string::const_iterator it = s.begin();
	while (it != s.end())
	{
		cout << *it << ' ';
		it++;
	}
	cout << endl;

	//反向迭代器
	string::const_reverse_iterator rit = s.rbegin();
	while (rit != s.rend())
	{
		cout << *rit << ' ';
		rit++;
	}
	cout << endl;
}

void test5()
{
	string s("Hello,world");
	cout << s << endl;
	cout << s.max_size() << endl;
	cout << s.size() << endl;
	cout << s.capacity() << endl;

	s.resize(15);
	cout << s << endl;
	cout << s.size() << endl;
	cout << s.capacity() << endl;

	s.resize(20, 'x');
	cout << s << endl;
	cout << s.size() << endl;
	cout << s.capacity() << endl;

	s.resize(9);
	cout << s << endl;
	cout << s.size() << endl;
	cout << s.capacity() << endl;

	s.reserve(100);
	cout << s.size() << endl;
	cout << s.capacity() << endl;

	s.shrink_to_fit();
	cout << s.size() << endl;
	cout << s.capacity() << endl;

	s.reserve(13);
	cout << s.size() << endl;
	cout << s.capacity() << endl;

	s.reserve(10);
	cout << s.size() << endl;
	cout << s.capacity() << endl;

	s.clear();
	cout << s.size() << endl;
	cout << s.capacity() << endl;

	if (s.empty())
	{
		cout << "字符串为空" << endl;
	}
	else
	{
		cout << "字符串不为空" << endl;
	}
}

void test6()
{
	string s("hello,world");
	cout << s << endl;

	cout << s.at(0) << endl;
	s.at(0) = 'x';
	cout << s << endl;

	s += "!!!!!!";
	cout << s << endl;

	s.push_back('x');
	cout << s << endl;

	s.append("HELLO");
	cout << s << endl;

	//插入多个字符
	s.insert(0, "11111");
	cout << s << endl;

	s.insert(6, "w");
	cout << s << endl;

	//插入单个字符
	s.insert(9, 1, 'w');
	cout << s << endl;

	//删除字符
	s.erase(0, 4);
	cout << s << endl;

	//迭代器用法
	s.erase(s.begin());
	cout << s << endl;
}

void test7()
{
	string s("hello,world");
	cout << s << endl;

	//插入单个字符
	s.replace(5, 1, 1, 'x');
	cout << s << endl;

	//插入多个字符
	s.replace(5, 1, " ");
	cout << s << endl;

	string s1("aaaaaaa");
	cout << s1 << endl;

	s.swap(s1);
	cout << s << endl;
	cout << s1 << endl;

	size_t pos = s1.find(' ');
	while (pos != string::npos)
	{
		s1.replace(pos, 1, "x");
		pos = s1.find(' ');
	}
	cout << s1 << endl;

	size_t pos1 = s1.find('o', 6);
	while (pos1 != string::npos)
	{
		s1.replace(pos1, 1, "x");
		pos1 = s1.find('o', 6);
	}
	cout << s1 << endl;

	size_t pos2 = s1.rfind('l', 4);
	while (pos2 != string::npos)
	{
		s1.replace(pos2, 1, " ");
		pos2= s1.rfind('l', 4);
	}
	cout << s1 << endl;
}

void test8()
{
	string s("How are you? I'm fine thank you. And you?");
	cout << s << endl;

	//查找并返回包含"AaBbCcDdEe"的所有为字符的位置
	size_t pos = s.find_first_of("AaBbCcDdEe");
	while (pos != string::npos)
	{
		s.replace(pos, 1, "*");
		pos = s.find_first_of("AaBbCcDdEe");
	}
	cout << s << endl;

	string s1 = s.substr(9);
	cout << s1 << endl;

	string s2 = s1.substr(9, 9);
	cout << s2 << endl;
}

void test9()
{
	string s;
	//cin >> s;
	//getline(cin, s);
	getline(cin, s, ',');
	cout << s << endl;

	string s("hello,world");
	cout << s << endl;

	string s1 = s + "xxxxx";
	cout << s1 << endl;

	string s2 = s + s1;
	cout << s2 << endl;

	string s3 = "aaaaa" + s2;
	cout << s3 << endl;

	//string s4 = "aaaa" + "bbbb";
}

int main()
{
	//test();
	//test1();
	//test2();
	//test3();
	//test4();
	//test5();
	//test6();
	//test7();
	//test8();
	test9();

	return 0;
}

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

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

相关文章

每日刷题(算法)

我们N个真是太厉害了 思路&#xff1a; 我们先给数组排序&#xff0c;如果最小的元素不为1&#xff0c;那么肯定是吹牛的&#xff0c;我们拿一个变量记录前缀和&#xff0c;如果当前元素大于它前面所有元素的和1&#xff0c;那么sum1是不能到达的值。 代码&#xff1a; #def…

elasticsearch实战应用

Elasticsearch(ES)是一种基于分布式存储的搜索和分析引擎&#xff0c;目前在许多场景得到了广泛使用&#xff0c;比如维基百科和github的检索&#xff0c;使用的就是ES。本文总结了一些使用心得体会&#xff0c;希望对大家有所帮助。 一、技术选型 说到全文搜索大家肯定会想到…

软件测试 BUG 篇

目录 一、软件测试的生命周期 二、BUG 1. bug的概念 2. 描述bug的要素 3. bug的级别 4. bug的生命周期 5. 与开发产生争执怎么办&#xff1f;&#xff08;面试高频考题&#xff09; 5.1 先检查自身&#xff0c;是否bug描述不清楚 5.2 站在用户角度考虑并抛出问题 5.3 …

[vue2+axios]下载文件+文件下载为乱码

export function downloadKnowledage(parameter) {return axios({url: /knowledage/download,method: GET,params: parameter,responseType: blob}) }添加 responseType: blob’解决以下乱码现象 使用触发a标签下载文件 downloadKnowledage(data).then((res) > {let link …

PHP及Java等其他语言转Go时选择GoFly快速快速开发框架指南

概要 经过一年多的发展GoFly快速开发框架已被一千多家科技企业或开发者用于项目开发&#xff0c;他的简单易学得到其他语言转Go首选框架。且企业版的发展为GoFly社区提供资金&#xff0c;这使得GoFly快速框架得到良好的发展&#xff0c;GoFly技术团队加大投入反哺科技企业和开…

模版进阶(template)

1.非类型模版参数 模版参数分类类型形参与非类型形参。 ① 类型形参&#xff1a;出现在在模板参数列表中&#xff0c;跟在class或者typename之类的参数类型名称。 ② 非类型形参&#xff0c;就是用一个常量作为类(函数)模板的一个参数&#xff0c;在类(函数)模板中可将该参数当…

Java键盘输入语句

编程输入语句 1.介绍:在编程中&#xff0c;需要接受用户输入的数据&#xff0c;就可以使用键盘输入语句来获取。 2.步骤&#xff1a; 1&#xff09;导入该类的所在包&#xff0c;java.util.* 2)创建该类对象&#xff08;声明变量&#xff09; 3&#xff09;调用里面的功能 3…

[2025]医院健康陪诊系统(源码+定制+服务)

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

计算机毕业设计 奖学金评定管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

MySQL ------- 索引(B树B+树)

阿华代码&#xff0c;不是逆风&#xff0c;就是我疯&#xff0c;希望本文内容能帮到你&#xff01;你们的点赞收藏是我前进最大的动力&#xff01;&#xff01; 目录 一&#xff1a;索引的特点 二&#xff1a;索引适用的场景 三&#xff1a;MySQL中索引操作 1&#xff1a;…

LTE SSS辅同步信号检测(相关法)

本文介绍一下SSS检测原理,本文采用联合检测算法,用复杂度来换取性能,适合工程上使用,SSS信号的产生往期已经介绍过了,这里就不介绍了。 1 SSS两个序列采用Interleaved结构而没有采用Localized集中式的原因是他比集中式可以获得更大的频率分集和干扰随机化效果。 2 根据3…

Python 从入门到实战22(类的定义、使用)

我们的目标是&#xff1a;通过这一套资料学习下来&#xff0c;通过熟练掌握python基础&#xff0c;然后结合经典实例、实践相结合&#xff0c;使我们完全掌握python&#xff0c;并做到独立完成项目开发的能力。 上篇文章我们讨论了面向对象简单介绍相关知识。今天我们将学习一…

828华为云征文 | 深度评测,华为云Flexus X实例在Sysbench性能测试中的亮眼表现

前言 本文章评测了华为云Flexus X实例在Sysbench性能测试中的亮眼表现。Flexus X凭借其新一代处理器和智能算力技术&#xff0c;在CPU、内存、磁盘I/O及网络性能上均展现出了卓越的能力。通过Sysbench的详尽测试&#xff0c;Flexus X实例在多核计算能力、内存吞吐量、磁盘响应速…

CSS传统布局方法(补充)——WEB开发系列37

开发技术不断演进&#xff0c;布局方式也经历了多个阶段的变革。从最初的基于表格布局到 CSS 的浮动布局&#xff0c;再到今天的弹性盒&#xff08;Flexbox&#xff09;与 CSS Grid 网格布局&#xff0c;每一种布局方式都有其独特的背景和解决特定问题的优势。 一、CSS Grid 出…

neo4j安装启动教程+对应的jdk配置

参考这位博主的视频教程&#xff1a;neo4j社区windows版下载 一、官网下载neo4j的安装包 &#xff08;1&#xff09;官网下载页面 &#xff08;2&#xff09;上一步 【download】之后&#xff0c;会自动下载&#xff0c;如果没有&#xff0c;点击【here】 这里可以看到一行字…

IDEA Project不显示/缺失文件

问题&#xff1a;侧边栏project 模式下缺少部分文件 先点close project 打开项目所在目录&#xff0c;删除目录下的.idea文件夹 重新open project打开这个项目即可解决

stm32单片机个人学习笔记4(GPIO输入)

前言 本篇文章属于stm32单片机&#xff08;以下简称单片机&#xff09;的学习笔记&#xff0c;来源于B站教学视频。下面是这位up主的视频链接。本文为个人学习笔记&#xff0c;只能做参考&#xff0c;细节方面建议观看视频&#xff0c;肯定受益匪浅。 STM32入门教程-2023版 细…

JavaDS —— 图

图的概念 图是由顶点集合以及顶点之间的关系组成的一种数据结构&#xff1a;G &#xff08;V&#xff0c;E&#xff09; 其中 V 表示的是顶点集合 &#xff1a; V { x | x 属于某个数据对象集} 是有穷非空集合 E 叫做边的集合 &#xff1a; E {(x, y) | x, y 属于 V} 或者 …

深度长文:揭开C/C++三目运算符的全部秘密,助你写出更优雅的代码(下)

在上篇文章中&#xff0c;我们深入探讨了三目运算符的基础语法、与if-else的对比以及使用中的常见误区。通过这些知识&#xff0c;你已经掌握了如何在代码中使用三目运算符来简化条件判断。 然而&#xff0c;三目运算符在C和C中的应用并不仅限于简单的条件选择。接下来&#x…

尚品汇-秒杀下单实现-页面轮询查询订单状态(五十三)

目录&#xff1a; &#xff08;1&#xff09;整合秒杀业务 &#xff08;2&#xff09;秒杀下单 &#xff08;3&#xff09;秒杀下单监听 &#xff08;4&#xff09;页面轮询接口 &#xff08;1&#xff09;整合秒杀业务 秒杀的主要目的就是获取一个下单资格&#xff0c;拥…