C++中string使用

目录

介绍

使用

迭代器(Iterator)

begin,end

rbegin,rend

容量(Capacity)

size,length

 capacity

 empty

clear

resize

reserve

元素访问(Element access)

operator[]

at

front,back

修饰符(Modifier)

opreator+=

push_back

insert

erase

pop_back

操作(operation)

c_str

copy

find

rfind

substr


介绍

     string属于STL(Standard Template Library,标准模板库)中容器的一部分。容器是用来存储和管理数据的对象。

     string表示字符串的字符串类。string的出现的时间比STL还要早所以里面的有些接口就会有点冗余。要使用string的话要加上名为<string>的头文件。这是关于使用string的网址:string,这里我就只是简单介绍一下某些接口的使用。

使用

迭代器(Iterator

     迭代器(iterator)是一种用于遍历容器中元素的对象。它提供了一种统一的方式来访问不同类型容器中的元素,无需了解容器的内部实现细节。这是封装的一种体现。

begin,end

     begin:返回字符串第一个字符的迭代器,end:返回字符串最后一个字符的迭代器。

     如果是空字符串使用它们会返回指向该空字符串起始位置的迭代器。利用它们就可以实现字符串的遍历。例:

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

void print(string& s)
{
	string::iterator it = s.begin();
	while (it != s.end())
	{
		cout << *it;
		it++;
	}
}

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

	print(s);
	return 0;
}//下面会频繁用到print这个函数

90fc77885c194ab0974fe90e2a51f0c5.png

     大家可能注意到了这个:

5095dbcd1466432282eb8d80961ab6be.png

     第一个it前面有个*号,第二个it后面面有个++。这里大家可能猜到了这就是指针!这里的迭代器也确实可以简单认为是指针,因为string开辟的空间是连在一起的。但是后面得list开辟的空间不是连续的就不能简单认为迭代器是指针。但是后面的list用迭代器遍历也是这样写的因为使用了运算符重载。

     如果不用对字符串里的内容修改就可以用cbegin,cend。这时候迭代器就要改为const_iterator。

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

	string::const_iterator it = s.cbegin();
	while (it != s.cend())
	{
		cout << *it;
		it++;
	}
	return 0;
}

rbegin,rend

     前面的r其实是reverse(“反转”“颠倒”“逆向”),所以rbegin:返回最后一个字符的迭代器,rend:返回第一个字符的迭代器。这时候迭代器就要改为reverse_iterator。这时就可以实现逆序打印字符串。例:

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

	string::reverse_iterator it = s.rbegin();
	while (it != s.rend())
	{
		cout << *it;
		it++;
	}
	return 0;
}

79f5acb9ee8644ada8795647de127e92.png

     大家可能好奇为什么不设计--来实现逆序打印。其实是为了保持语言的一致性、清晰性、可维护性。

     如果不用对字符串里的内容修改就可以用crbegin,crend。这时候迭代器就要改为const_reverse_iterator。

容量(Capacity

size,length

     以字节为单位返回有效字符串的长度。

     size和length的功能是一样的,这是因为string设计的比STL要早原来的string里没有size为了实现统一性就设计了size。使用例子:

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

	cout << s.size();

	return 0;
}

9f5efba85ea2428ea99a6bb6b69a0dcc.png

 capacity

     以字节为单位返回当前为字符串分配的存储空间大小。使用例子:

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

	cout << s.capacity();

	return 0;
}

562b909c28e8475fa795acead93e0287.png

 empty

     这是判断字符串是否为空。为空则真,否则为假。使用例子:

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

	cout << s.empty();

	return 0;
}

8fe5ee1680ae4b37b5a1a3eec83f649c.png

clear

     将字符串里的所有的字符删除。使用例子:

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

	s.clear();

	print(s);
	return 0;
}

e798afb4af3e48d0b2edec0efb79c204.png

resize

     将字符串调整为长度为 n 个字符。

  • 如果n小于字符串的长度

          如果n小于字符串的长度,会保留第一个到第n个之间的所有字符,后面的字符都会被移除。使用例子:

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

	s.resize(5);

	print(s);
	return 0;
}

2a30e0fdaf7a4943856e0095b0cd5905.png

  • 如果n大于或等于字符串的长度

          如果n大于或等于字符串的长度就会从最后一个字符开辟n - l(字符串的长度)。可以在最后一个字符的后面新增新的字符,也可以不新增。使用例子:

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

	s.resize(15, 'a');

	print(s);
	return 0;
}

4c834bc7e6f7472db152eeba60cd7efa.png

reserve

     用于预分配n个字符数量的内存空间以容纳字符串内容,使其能够容纳最多 n 个字符。

     如果 n 大于当前字符串的容量,这个函数会使容器增加其容量到 n 个字符(或更多)。其他情况下,它被视为一个非约束性的请求来缩小字符串容量(一般不会缩小)。使用例子:

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

	s.reserve(20);
	cout << s.capacity();

	return 0;
}

78ae7cf38edf471b8fce36a4a6d3e4bd.png

     大家可能发现了这里的值是31并不是20。因为扩容是按照固定的倍数扩的编译器具体扩多大是由它决定的。我们想把容量变成20其实对于编译器来说就只是一个建议,编译器可能会扩成20也有可能扩成比它大的某数字。

元素访问(Element access

operator[]

     获取字符串中pos位置的字符,并返回字符串中 pos 位置的字符的引用。

     如果访问超出字符串长度的位置,会导致未定义行为。可能出现程序崩溃、产生错误的结果等。这个就很像是数组里的下标运算符。事实上它就是重载了数组里的下标运算符。使用例子:

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

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

	return 0;
}

fe8dbe4d72d04caa881b7f3287ab6032.png

at

      at和上面的operator[]几乎一样,也是访问字符串里的字符并返回该字符引用。如果访问的位置超出字符串长度就会抛异常。使用例子:

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

	for (size_t i = 0; i < s.size(); i++)
	{
		cout << s.at(i);
	}

	return 0;
}

8f2d55b41de64421ac707b1360edeec5.png

front,back

     front,back和上面的begin,end几乎一样只不过,front:返回的是第一个字符的引用,back:返回的是最后一个字符的引用。空字符串里不能使用它们。使用例子:

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

	s.front() = 'A';
	s.back() = 'A';

	print(s);
	return 0;
}

550c1a5c71be4f98902b8c460fca094e.png

修饰符(Modifier

     对字符串进行各种操作和变换,以满足不同的需求。

opreator+=

     在字符串末尾添加字符或字符串,并增加有效长度。该接口会返回字符串类的引用。使用例子:

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

	s += ' ';
	s += "abc";

	print(s);
	return 0;
}

e7968cb255384fd2b1134f120cb8ba45.png

push_back

     在字符串末尾添加字符,使有效地将其长度增加一个。使用例子:

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

	s.push_back('a');

	print(s);
	return 0;
}

1797a73c852f4880863198616566870f.png

insert

     在字符串的指定pos位置之前插入字符或字符串。

     第一个参数是插入位置的下标,如果插入位置的下标超出字符串长度就会抛异常。第二个参数可以是字符串,可以是字符但要在字符写要插入字符的长度。该接口返回字符串类的引用。使用例子:

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

	const char* str = "---";
	s.insert(0, 1, 'a');
	s.insert(1,str);

	print(s);
	return 0;
}

095f30a953a24863b90accbe5f6d5c24.png

erase

     擦除字符串的一部分,减少其有效长度。

     第一个参数是要擦处位置的下标,如果擦除位置的下标超出字符串长度就会抛异常 。第二个参数是要删除字符的长度。如果要删除字符的长度不写或超出字符串有效长度就会把后面的所有的字符都删除。使用例子:

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

	s.erase(0, 1);

	print(s);
	return 0;
}

c7fdc39c1c784199bfa326937dfb6e0a.png

     如果没接len:

a5f94deac499403c995c0e8764f984ef.png

pop_back

     在字符串末尾删除字符,使有效地将其长度减少一个。使用例子:

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

	s.pop_back();

	print(s);
	return 0;
}

46117966ecde4bce8ffcd4fc01b9b696.png

操作(operation

     对字符串进行一些操作例如查找,复制等。

c_str

     该接口会返回一个指向字符数组的指针。使用例子:

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

	const char* p = s.c_str();
	printf("%p", p);
	cout << endl << p;

	return 0;
}

a6fa7a6ff7ed44d3ab72644ff26326ff.png

     大家可能注意到了cout << p直接就打印了p的内容了,这是因为string里重载了<<。

copy

     将字符串里的内容拷贝到字符数组里,需要注意的是并不会拷贝'\0'。该接口返回实际拷贝的字符数。

     第一个参数的位置是字符数组指针,第二个参数是要拷贝字符的长度,第三个参数是字符串里开始拷贝位置的下标(默认是0)。使用例子:

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

	char buffer[20];
	size_t len = s.copy(buffer, 5);
	buffer[len] = '\0';
	cout << buffer;

	return 0;
}

6384c8970ab840b9bc03fdea5a2f6822.png

find

     查找pos位置之后第一次出现的字符和字符串。

     第一个参数是要查到的字符串或字符,第二个参数是查找的起始位置pos(默认是0)。如果找到会返回该下标位置,否则返回npos。使用例子: 

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

	size_t i = s.find('o');
	i != s.npos ? cout << "找到了,下标是" << i: cout << "没找到";

	return 0;
}

307101b5985e4af2a69d8444f84a0ff9.png

npos:

  1. 当在字符串的成员函数中作 len 参数的缺省值时,这时意味着“直到字符串的末尾”。
  2. 作为返回值,它通常用于表示没有匹配。
  3. 这个常量被定义为值 -1,由于 size_t 是一个无符号整数类型,所以这是该类型的最大可表示值。

rfind

     查找pos位置之前第一次出现的字符和字符串。

     第一个参数是要查到的字符串或字符,第二个参数是查找的起始位置pos(默认是npos)。如果找到会返回该下标位置,否则返回npos。使用例子:

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

	size_t i = s.rfind('o');
	i != s.npos ? cout << "找到了,下标是" << i : cout << "没找到";

	return 0;
}

68477cd211cf4eda98dd7a43ef1f7b82.png

substr

     从字符串里提取子字符串。

     第一个参数是子字符串开始的位置,第二个参数是提取子字符串的长度(如果不写会从起始位置到字符串结束)。该接口返回字符串类。使用例子:

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

	string str = s.substr(0, 5);
	print(str);

	return 0;
}

57c89c7759b1488689be2e37828ae86e.png

     上面我所提到的接口一定要多练习,千万不要只看不练。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值