C++:string 类详解

发布于:2024-09-17 ⋅ 阅读:(198) ⋅ 点赞:(0)

目录

简介

使用

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

析构函数

赋值运算符重载(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;
}