C++STL:string类的使用

Posted 山舟

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++STL:string类的使用相关的知识,希望对你有一定的参考价值。


前言

STL中的内容很多,所以文章中只介绍最常用、最好用的一部分。如果需要用到剩余的一些内容,可以到C++的官方网站上查找。


一、 string类

C语言中没有字符串这一类型,只能通过char数组来间接实现,字符串是以’\\0’结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分离开的,而且底层空间需要用户自己管理,可能还会非法访问。

string是表示字符串的字符串类,该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作,包含在string头文件下(注意不是string.h)。


二、 string类的常用函数

1.构造函数

STL库中给出了下面7个构造函数,其中(1)、(2)和(4)最常用

使用如下:

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

	return 0;
}

结果如下:


2.赋值运算符重载

代码如下:

int main()
{
	std::string str1, str2, str3;
	str1 = "hello world";
	str2 = 'x';
	str3 = str1;
	cout << str1 << endl;
	cout << str2 << endl;
	cout << str3 << endl;

	return 0;
}

结果如下:


3.三种遍历方式

(1)operator[]重载、下标

下面的代码中s.size()返回string中有效字符的个数(即不包含\\0)

代码如下:

int main()
{
	string s = "12345";
	size_t i = 0;
	for (i = 0; i < s.size(); i++)
		cout << s[i] << " ";
	cout << endl;

	return 0;
}

结果如下:


(2)范围for

代码如下:

int main()
{
	string s = "12345";
	for (auto e : s)
		cout << e << " ";
	cout << endl;
	return 0;
}

结果如下:


(3)迭代器

迭代器是各种STL容器遍历时通用的方法,对于string、vector这种简单的容器来说可能与其他遍历方法差不多,但到之后复杂的容器时用迭代器遍历是最方便的。

代码如下:

int main()
{
	string s = "12345";
	string::iterator it = s.begin();//前面加string告诉编译器找string类里的iterator
	//而不是去找其他容器的iterator
	
	while (it != s.end())//注意判断条件
	{
		cout << *it << " ";
		it++;//it向后遍历
	}
	cout << endl;

	return 0;
}

结果如下:

begin()返回第一个字符的迭代器、end()返回最后一个字符下一个位置的迭代器。

这里是第一次遇到迭代器,可以暂时将其理解为一个指针,但迭代器不一定全是指针,即下面的写法:

代码如下:

class string
{
public:
	typedef char* iterator;
	//...
private:
	//...
}

还有反向迭代器可实现反向遍历,与上面正向迭代器同理。

代码如下:

int main()
{
	string s = "12345";
	string::reverse_iterator it = s.rbegin();//ebegin()返回最后一个字符的迭代器
	while (it != s.rend())//rend()返回第一个字符前一个位置的迭代器。
	{
		cout << *it << " ";
		it++;//注意这里是++而不是--
	}
	cout << endl;

	return 0;
}

结果如下:


由上可知,迭代器遍历时区间是左闭右开的,即[begin(), end())、[rbegin(), rend()),begin()和rbegin()位置是可以被访问的,而end()和rend()位置不能被访问。


4.数据的插入与删除

(1)尾部插入数据

用push_back在字符串末尾插入单个字符,用append插入字符串。

代码如下:

int main()
{
	string s;
	s.push_back('h');
	s.push_back('e');
	s.push_back('l');
	s.push_back('l');
	s.push_back('o');
	s.push_back(' ');
	cout << s << endl;

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

	string s1 = "!!!";
	s.append(s1);
	cout << s << endl;

	return 0;
}

结果如下:


但实际情况中重载的operator+=是最方便的。

代码如下:

int main()
{
	string s;
	s += 'h';
	s += 'e';
	s += 'l';
	s += 'l';
	s += 'o';
	s += ' ';
	cout << s << endl;

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

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

	return 0;
}

结果如下:


注意:
(1)在string尾部追加字符时,push_back、append和+=三种的实现方式差不多,一般情况下string类的+=操作用的比较多,+=操作不仅可以连接单个字符,还可以连接字符串,而且写起来可读性很好。
(2)对string操作时,如果能够大概预估到要存储多少个字符,可以通过reserve提前把空间预留好。

(2)insert任意位置插入数据

注意是在给定的位置(下标)之后插入数据。

代码如下:

int main()
{
	string s = "ad";
	cout << s << endl;

	s.insert(0, "bc");
	cout << s << endl;
	
	s.insert(4, "efg");
	cout << s << endl;

	s.insert(1000, "!!!");//一定要在合法的位置插入数据,否则会报错
	cout << s << endl;

	return 0;
}

结果如下:


(3)erase任意位置清除数据

注意是在给定的位置(下标)之后清除数据。

代码如下:

int main()
{
	string s = "abcdefg";

	s.erase(0, 1);//清除下标为0的位置后的1个数据
	cout << s << endl;

	s.erase(5, 10);//清除下标为5的位置后的10个数据,由于其后没有10个数据,所以全部清除结束
	cout << s << endl;

	s.erase(2);//清除下标为2的位置后的所有数据
	cout << s << endl;

	return 0;
}

结果如下:


5.resize与reserve

(1)resize

改变一个string对象的size,即对象中有效字符的个数。

代码如下:

int main()
{
	string s1 = "abcd";
	cout << "size:" << s1.size() << endl;
	cout << "capacity:" << s1.capacity() << endl;
	cout << s1 << endl << endl;

	s1.resize(2);//size大于给定的值,则只保留给定的值的内容
	cout << "size:" << s1.size() << endl;
	cout << "capacity:" << s1.capacity() << endl;
	cout << s1 << endl << endl;

	s1.resize(5);//size小于给定的值,多余的部分默认给\\0
	cout << "size:" << s1.size() << endl;
	cout << "capacity:" << s1.capacity() << endl;
	cout << s1 << endl << endl;

	s1.resize(7, '!');//size小于给定的值,多余的部分也可给定,如这里给定为!
	cout << "size:" << s1.size() << endl;
	cout << "capacity:" << s1.capacity() << endl;
	cout << s1 << endl << endl;

	return 0;
}

结果如下:


注意上面结果中最后的字符串中间出现了三个空格,这里其实是s1.resize(5);时默认填充的三个\\0,但由于其是不可见字符,所以看起来是空格。


(2)reserve

即改变一个string对象的capacity,即对象中能存储有效字符的最大个数。

代码如下:

int main()
{
	string s;
	int prev = s.capacity();//获取当前string对象的capacity大小
	for (char ch = 0; ch < 127; ch++)
	{
		s += ch;
		//发生增容时打印capacity的变化
		if (prev != s.capacity())
		{
			cout << "capacity:" << prev << "-->>" << s.capacity() << endl;
			prev = s.capacity();
		}
	}
	return 0;
}

结果如下:


6.c_str

返回C语言类型的字符串,即遇到\\0截止。

代码如下:

int main()
{
	string s = "abcd";
	s.resize(6);
	s += "!!!";
	cout << s.c_str() << endl;
	cout << s << endl;
	return 0;
}

结果如下:


resize时不够的两个位置默认用\\0补全,打印c_str遇到第一个\\0即停止,而直接打印s会打印[0,s.size())的全部内容。


7.查找

find函数用来查找一个string对象内有无某一字符或字符串并返回下标,找不到返回npos。
npos是string内的一个静态成员,类型为unsigned int,值为无符号整型的最大值。

代码如下:

int main()
{
	string s = "hello world";
	size_t pos = s.find(' ');
	
	if (pos != string::npos)//判断是否找到
	{
		for (; pos < s.size(); pos++)
			cout << s[pos];
		cout << endl;
	}
	
	size_t pos1 = s.find('z');
	if (pos1 == string::npos)
		cout << "找不到" << endl;
	
	return 0;
}

结果如下:


同理也有rfind函数,即倒着查找某一字符或字符串,此处不再赘述。


8.getline

cin相当于C语言中的scanf,遇到空格或换行停止读入;getline相当于C语言中的gets,遇到换行停止读入。

代码如下:

int main()
{
	string s;
	getline(cin, s);//注意写法
	cout << s << endl << endl;

	cin >> s;
	cout << s << endl;
	return 0;
}

结果如下:


感谢阅读,如有错误请批评指正

以上是关于C++STL:string类的使用的主要内容,如果未能解决你的问题,请参考以下文章

stl中String类的实现

c++_STL_string类简介

c++_STL_string类简介

(C++基础_STL) —— string类的基本应用

(C++基础_STL) —— string类的基本应用

(C++基础_STL) —— string类的基本应用