【C++】STL之String

STL简介
什么是STL

STL是一些“容器”的集合,这些“容器”有list,vector,set,map等,STL也是算法和其他一些组件的集合。这里的“容器”和算法的集合指的是世界上很多聪明人很多年的杰作。STL的目的是标准化组件,这样就不用重新开发,可以使用现成的组件。STL现在是C++的一部分,因此不用安装额外的库文件。

STL的版本

原始版本:Alexander Stepanov、Meng Lee 在惠普实验室完成的原始版本,本着开源精神,他们声明允许任何人任意运用、拷贝、修改、传播、商业使用这些代码,无需付费。唯一的条件就是也需要向原始版本一样做开源使用。 HP版本–所有STL实现版本的始祖。

P.J.版本:由P. J. Plauger开发,继承自HP版本,被Windows Visual C++采用,不能公开或修改,缺陷:可读性比较低,
符号命名比较怪异。

RW版本:由Rouge Wage公司开发,继承自HP版本,被C+ + Builder 采用,不能公开或修改,可读性一般。

SGI版本:由Silicon Graphics Computer Systems,Inc公司开发,继承自HP版 本。被GCC(Linux)采用,可移植性好,
可公开、修改甚至贩卖,从命名风格和编程 风格上看,阅读性非常高。

STL的六大组件

空间配置器allocator
容器string,vector,list,deque,map,set,multimap.mutilset

配接器stack,queue,priority_queue

仿函数:greater,less

算法find,swap,reverse,sort,merge

迭代器iterator,const_iterator,reverse_iterator,const_reverse_iterator

string

概念:string是C++、java、VB等编程语言中的字符串,字符串是一个特殊的对象,属于引用类型。 在java、C#中,String类对象创建后,字符串一旦初始化就不能更改,因为string类中所有字符串都是常量,数据是无法更改,由于string对象的不可变,所以可以共享。对String类的任何改变,都是返回一个新的String类对象。 C++标准库中string类以类型的形式对字符串进行封装,且包含了字符序列的处理操作

string类的常见接口
1.构造函数
函数名称功能简述
string()构造空的string类对象
string(const char* s)用C-string来构造string对象
string(size_t n,char c)string类对象中包含n个字符c
string(const string&s)拷贝构造
string(const string&s,size_t n)从s中第n位起的字符够造成一个新的string类对象
void TestString()
{
	string s1;
	string s2("hello");
	string s3(10, 'd');
	string s4(s2);
	string s5(s2, 1);

	cout << "s1=" << s1 << endl;
	cout << "s2=" << s2 << endl;
	cout << "s3=" << s3 << endl;
	cout << "s4=" << s4 << endl;
	cout << "s5=" << s5 << endl;
}
输出
s1=
s2=hello
s3=dddddddddd
s4=hello
s5=ello
2.容量操作
函数名称功能简述
size_t size() const返回字符串有效字符长度
size_t length() const返回字符串有效字符长度
size_t caoacity() const返回空间总大小
bool empty() const判断字符串是否为空,是返回true,否返回false
void clear()清空字符串
void resize(size_t n,char c)将有效字符的个数改成n个,多余的空间用字符c进行填充
void resize(size_t n)将有效字符的个数改成n个,多余的空间用0进行填充
void reserve(size_t res_arg=0)为字符串预留空间
void TestString1()
{
	string s1("abcdef");
	cout << "s1.size()=" << s1.size() << endl;
	cout << "s1.length()=" << s1.length() << endl;
	cout << "s1.capacity()=" << s1.capacity() << endl;
	cout << "s1.empty()=" << s1.empty() << endl;
	s1.clear();
	cout << "s1.clear()=" << s1 << endl;
	cout << "s1.capacity()=" << s1.capacity() << endl;
	string s2("hello");
	cout << "s2=" << s2 << endl;
	s2.resize(50, 'a');
	cout << "s2.resize(50,'a')=" << s2 << endl;
	cout << "s2.capacity()=" << s2.capacity() << endl;
	s2.resize(3, 'b');
	cout << "s2.resize(3,'b')=" << s2 << endl;
	cout << "s2.capacity()=" << s2.capacity() << endl;
	string s3("hehe");
	s3.reserve(100);
	cout << "s3.size()=" << s3.size() << endl;
	cout << "s3.capacity()=" << s3.capacity() << endl;
	string s4("abcd");
	s4.reserve(2);
	cout << "s4.size()=" << s4.size() << endl;
	cout << "s4.capacity()=" << s4.capacity() << endl;
}
输出
s1.size()=6
s1.length()=6
s1.capacity()=15
s1.empty()=0
s1.clear()=
s1.capacity()=15
说明clear()只会清空字符串,而不是删除字符串
s2=hello
s2.resize(50,'a')=helloaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
s2.capacity()=63
说明resize(n,'c')当n大于当前的capacity会自动增容,多余的空间用'c'进行填充
s2.resize(3,'b')=hel
s2.capacity()=63
说明resize(n,'c')当n小于当前的capacity,capacity不变,多余的空间用'c'进行填充
s3.size()=4
s3.capacity()=111
s4.size()=4
s4.capacity()=15
说明reserve(n)之后,size()和length()的大小不变,只是capacity不够时会自动增容
3.访问操作
函数名称功能简述
char& operator[] (size_t pos)返回pos位置的字符 const string类对象调用
const char& operator[] (size_t pos) const返回pos位置的字符,非const string类对象调用
void TestString2()
{
	string s1("abcdef");
	const string s2("ABCDEF");
	cout << "s1=" << s1 << endl;
	cout << "s1[2]=" << s1[2] << endl;
	for (size_t i = 0;i < s1.size();++i)
	{
		cout << s1[i] << endl;
	}
	s1[0] = 'h';
	cout << "执行s1[0] = 'h'后" << endl;
	cout << "s1=" << s1 << endl;
	cout << "s2=" << s2 << endl;
	cout << "s2[2]=" << s2[2] << endl;
	//s2[0] = 'H';会报错const类型不可被修改
}
输出
s1=abcdef
s1[2]=c
a
b
c
d
e
f
执行s1[0] = 'h'后
s1=hbcdef
s2=ABCDEF
s2[2]=C
4.修改操作
函数名称功能简述
void push_back(char c)在字符串最后尾插字符c
string& append(const string* s)在字符串最后追加一个字符串
string& operator+=(const string& str)在字符串最后追加字符串str
string& operator+=(char c)在字符串最后追加字符c
const char* c_str()const返回C格式字符串
size_t find(char c,size_t pos=0)const从字符串第pos个位置开始往后找字符c,返回c在字符串中的位置,若不存在返回-1
size_t rfind(char c,size_t pos =npos)从字符串第pos个位置开始往前找字符c,返回c在字符串中的位置,若不存在返回-1
string substr(size_t pos=0,size_t n=npos) const在字符串中从pos位置开始,截取n个字符,然后将其返回
void TestString3()
{
	string s1("a");
	s1.push_back('b');
	cout << "执行s1.push_back('b')后" << endl;
	cout << s1 << endl;
	s1 = s1.append("cd");
	cout << "执行s1 = s1.append(cd)后" << endl;
	cout << s1 << endl;
	string s2("e");
	s1 += s2;
	cout << "执行s1 += s2;s2=e后" << endl;
	cout << s1 << endl;
	s1 += "fh";
	cout << "执行s1 += fh;后" << endl;
	cout << s1 << endl;
	s1 += 'j';
	cout << "执行s1 += 'j';后" << endl;
	cout << s1 << endl;
	int num1 = s1.find('c', 0);
	cout << num1 << endl;
	int num2 = s1.rfind('c', 5);
	cout << num2 << endl;
	int num3 = s1.find('z', 0);
	cout << num3 << endl;
	string s3 = s1.substr(0, 3);
	cout << s3 << endl;
	string s4 = s1.substr(7, 3);
	cout << s4 << endl;
	cout << s1.c_str() << endl;//相当于将s1打印一遍
}
输出
执行s1.push_back('b')后
ab
执行s1 = s1.append(cd)后
abcd
执行s1 += s2;s2=e后
abcde
执行s1 += fh;后
abcdefh
执行s1 += 'j';后
abcdefhj
2
2
-1
abc
j
abcdefhj
void TestString4()
{
	//取文件后缀
	string s1("file.cpp");
	size_t pos = s1.find('.');//直接就可以得到'.'的位置
	string s2 = s1.substr(pos, s1.size() - pos);
	cout << s2 << endl;

	//取域名
	string s3("http://www.cplusplus.com/reference/string/string/append/");
	cout << s3 << endl;
	string s4("https://baike.baidu.com/item/%E8%BF%AD%E4%BB%A3%E5%99%A8/3803342?fr=aladdin");
	cout << s4 << endl;
	size_t start = s4.find("://");
	start += 3;
	size_t finish = s4.find('/', start);
	cout << s4.substr(start, finish - start) << endl;	
}
输出
.cpp
http://www.cplusplus.com/reference/string/string/append/
https://baike.baidu.com/item/%E8%BF%AD%E4%BB%A3%E5%99%A8/3803342?fr=aladdin
baike.baidu.com
5.非成员函数
函数名称功能简述
operator+加法运算符重载
operator>>输入运算符重载
operator<<输出运算符重载
getline获取一行字符串
relational operators大小比较
void TestString5()
{
	string s1("ab");
	string s2("cde");
	cout << s1 + s2 << endl;
	string s3;
	getline(cin, s3);
	cout << s3 << endl;
	cout << (s1 < s2)<< endl;//比较的是size
	cout << (s1 > s2) << endl;
	cout << (s1 == s2) << endl;
	cout << (s1 >= s2) << endl;

}
输出
abcde
ee
ee
1
0
0
0
深拷贝
class String
{
public:
	/*String()
		:_str(new char[1])
	{
		_str[0] = '\0';
	}
	String( char* str)
		:_str(new char[strlen(str) + 1])
	{
		strcpy(_str, str);
	}*/
	//可以将这两合并成一个全缺省参数的函数
	String(const char* str = "")
		:_str(new char[strlen(str) + 1])
	{
		strcpy(_str, str);
	}
	String(const String& s)
		:_str(new char[strlen(s._str) + 1])
	{
		strcpy(_str, s._str);
	}
	~String()
	{
		if (_str)
		{
			printf("~String()\n");
			delete[] _str;
			_str = nullptr;
		}
	}
	String operator=(const String& s)
	{
		if (this != &s)//写了这个才可以实现自己给自己赋值
		{
			//不管哪个长都把旧的给释放掉
			delete[] _str;
			_str = new char[strlen(s._str) + 1];
			strcpy(_str, s._str);
			return *this;
		}
	}
	char& operator[](size_t index)
	{
		return _str[index];
	}

	const char* c_str()
	{
		return _str;
	}
private:
	char* _str;
};

迭代器

迭代器是能够用来遍历STL容器中元素的一种对象,也可以理解成一个复杂的指针,它还提供一些基本操作符:*、++、==、!=、=。具有遍历各种复杂数据结构的能力,但是它的底层机构取决于其所遍历的数据结构,因此,每种容器都会提供属于自己的迭代器。
    typedef char* Iterator;
	Iterator Begin() const
	{
		return _str;
	}
	Iterator End() const
	{
		return _str + _size;
	}
	typedef char* Const_Iterator;
	Const_Iterator Const_Begin() const
	{
		return _str;
	}
	Const_Iterator Const_End() const
	{
		return _str + _size;
	}
范围:左闭右开[)
void Iterator()
{
	string s1("abcdef");
	string::iterator it1 = s1.begin();
	while (it1 != s1.end())
	{
		cout << *it1 << endl;
		++it1;
	}
}
迭代器的第一个位置指向s1的第一个位置
迭代器最后一个位置指向s1最后一个位置的下一个位置
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值