C++——string类的使用介绍

目录

一、什么是string类

二、string类的使用

1、string类对象的常见构造

2、string类对象的容量操作

3、string类对象的访问及遍历操作

4、string类对象的修改操作

5、string类非成员函数

6、其他函数


一、什么是string类

1. 字符串是表示字符序列的类

2. 标准的字符串类提供了对此类对象的支持,其接口类似于标准字符容器的接口,但添加了专门用于操作单字节字符字符串的设计特性。

3. string类是使用char(即作为它的字符类型,使用它的默认char_traits和分配器类型(关于模板的更多信息,请参阅basic_string)。

4. string类是basic_string模板类的一个实例,它使用char来实例化basic_string模板类,并用char_traits和allocator作为basic_string的默认参数(根于更多的模板信息请参考basic_string)。

5. 注意,这个类独立于所使用的编码来处理字节:如果用来处理多字节或变长字符(如UTF-8)的序列,这个类的所有成员(如长度或大小)以及它的迭代器,将仍然按照字节(而不是实际编码的字符)来操作

总结:

1. string是表示字符串的字符串类

2.该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。

3. string在底层实际是:basic_string模板类的别名,typedef basic_string<char, char_traits, allocator> string;

4.不能操作多字节或者变长字符的序列。

5. 在使用string类时,必须包含#include头文件以及using namespace std。

二、string类的使用

1、string类对象的常见构造

函数名称 功能

string s;

构造空的string类对象,即空字符串

string s1(const char* s);

复制s指向的字符串

string s2(size_t n,char c);

生成n个c字符的字符串

string s3(const string&s); 用string类对象拷贝构造

具体使用:

    string s;         // 构造空的string类对象s

	string s2("hello");//复制hello字符串给s2对象

	string s3(10, 'x');//生成10个x的字符串

	string s4(s2);     //用s2拷贝构造对象s4

2、string类对象的容量操作

函数 功能
size 返回字符串有效个数
length 返回有效字符串个数
capacity 返回总空间的大小
empty 判断字符串是否为空
clear 清空字符串
reserve 为字符串预留空间(有点像malloc)
resize 将有效的字符个数改成n个,多出的空间用字符c填充(有点像calloc)

具体使用: 

void test2()
{
	string s("hello");

	cout <<"size:"<< s.size() << endl;
	cout <<"length:"<< s.length() << endl;
	cout <<"capacity:"<< s.capacity() << endl;
	cout <<"empty:"<< s.empty() << endl;
}

结果如下: 

 对于clear函数,只是将s中的字符串清空,size置为0,但是不改变底层空间capacity的大小

void test2()
{
	string s("hello");

	cout <<"size:"<< s.size() << endl;
	cout <<"length:"<< s.length() << endl;
	cout <<"capacity:"<< s.capacity() << endl;
	cout <<"empty:"<< s.empty() << endl;
	cout << "----------" << endl;
	s.clear();
	cout << "size:" << s.size() << endl;
	cout << "capacity:" << s.capacity() << endl;
	cout << "empty:" << s.empty() << endl;

}

 我们再来详细看看resize

void resize (size_t n);
void resize (size_t n, char c);

①按照给定的字符扩容

void test3()
{
	string s("hello");
	s.resize(10, 'x');//将s中的有效字符个数增加到10个,后面多出的位置用x填充
	cout << "size:" << s.size() << endl;
	cout << "capacity:" << s.capacity() << endl;
	cout << s << endl;
}

结果如下: 

②默认给定的“\0”来填充扩容

void test4()
{
	string s("hello");
	s.resize(15);//将s中的有效字符个数增加到15个,后面多出的位置用"\0"填充
	cout << "size:" << s.size() << endl;
	cout << "capacity:" << s.capacity() << endl;
	cout << s << endl;
}

 结果如下:

③当是缩小大小时,会截断字符

void test5()
{
	string s("hello");
	s.resize(3);//将s中的有效字符个数减少到3个,只剩下原来的前三个
	cout << "size:" << s.size() << endl;
	cout << "capacity:" << s.capacity() << endl;
	cout << s << endl;
}

结果如下:

 我们再来详细看看reserve

void reserve (size_t n = 0);

①当n大于当前对象的容量时,将容量扩大到n或者大于n

void test6()
{
	string s;
	cout << "size:" << s.size() << endl;
	cout << "capacity:" << s.capacity() << endl;
	cout << "----------------" << endl;
	s.reserve(100);//将原来的capacity扩大到100
	cout << "size:" << s.size() << endl;
	cout << "capacity:" << s.capacity() << endl;
}

结果如下:

 ②当n小于容量时,不会缩小到容量

void test6()
{
	string s;
	cout << "size:" << s.size() << endl;
	cout << "capacity:" << s.capacity() << endl;
	cout << "----------------" << endl;
	s.reserve(100);//将原来的capacity扩大到100
	cout << "size:" << s.size() << endl;
	cout << "capacity:" << s.capacity() << endl;
	cout << "----------------" << endl;
	s.reserve(20);//不会将之前的capacity缩小
	cout << "size:" << s.size() << endl;
	cout << "capacity:" << s.capacity() << endl;
}

结果如下:

我们可以看到容量并没有缩小!!!

总结:

① resize(size_t n) 与 resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不同的是当字符个数增多时:resize(n)用0来填充多出的元素空间,resize(size_t n, char c)用字符c来填充多出的元素空间。注意:resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间总大小不变。

② reserve(size_t res_arg=0):为string预留空间,不改变有效元素个数,当reserve的参数小于string的底层空间总大小时,reserve不会改变容量大小

3、string类对象的访问及遍历操作

函数 功能
operator[ ](i)和s[i]

返回i位置的字符,const string类对象的调用

begin+end begin获取第一个字符的迭代器,end获取最后一个字符的下一个位置的迭代器
rbegin+rend rbegin反向获取第一个字符的迭代器,rend反向获取最后一个字符的下一个位置的迭代器
范围for C++11支持更简洁的范围for遍历方式

operator[ ](i)

char& operator[] (size_t pos);
const char& operator[] (size_t pos) const;

我们知道string类字符串的底层其实是数组实现的,于是我们可以采用下标的方式进行遍历。这里的operator[ ](i)和s[i]其实是完全一样的,只不过后者使用更加方便。他们返回对位于字符串中pos位置的字符的引用。

举例说明:

void test7()
{
	string s1("hello");
	const string s2("HELLO");
	cout << s1 << " " << s2 << endl;
	cout << s1[0] << " " << s2[0] << endl;

	s1[0] = 'x';
	cout << s1 << endl;

	//s2[0] = 'x';const类对象不能修改
}

三种遍历操作:(常用)

①operator[ ]的用法

void test8()
{	
	string s1("hello");
	string s2(s1);//拷贝构造
	for (size_t i = 0; i < s2.size(); ++i)
	{
		cout << s2.operator[](i) << " ";
		cout << s2[i] << " ";
	}
	cout << endl;
	for (size_t i = 0; i < s2.size(); ++i)
	{
		s2[i] += 1;//支持修改
	}
	cout << s2 << endl;
}

②迭代器

注意:这里暂时将迭代器想象成像指针一样的类型

void test9()
{
	string s("hello");
	//迭代器的用法
	string::iterator it = s.begin();
	while (it !=s.end())
	{
		cout << *it << endl;
		++it;
	}
}

③范围for

其实范围for的底层是将它给处理成了迭代器

void test10()
{
	string s("hello");
	for (auto ch : s)
		cout << ch << endl;
	//把s中的每个字符取出来,赋值给ch,不需要++,判断结束,自动往后迭代
}

4、string类对象的修改操作

函数 功能
push_back 在字符串后面尾插字符c
append 在字符串后面追加字符串
operator+= 在字符串后面追加字符串
c_str 返回C格式字符串
find+npos 从字符串pos位置开始,往后找字符c,返回该字符在字符串中的位置
rfind 从字符串pos位置开始,往前找字符c,返回该字符在字符串中的位置
substr 在字符串中,从pos位置开始,截取n个字符,然后将其返回

①push_back

void push_back (char c);
void test11()
{
	string s("xxx");
	cout << s << endl;
	s.push_back('H');
	s.push_back('E');
	s.push_back('L');
	s.push_back('L');
	s.push_back('O');
	cout << s << endl;//将HELLO依次拼接到xxx后面
}

结果如下:

②append 

string& append (const string& str);
string& append (const char* s);
void test12()
{
	string s1("hello");
	string s2("C++");
	s1.append(s2);//直接拼接一个对象字符串

	cout << s1 << endl;
	s1.append("haha");//直接拼接一个字符串
	cout << s1 << endl;
}

 ③operator+=(这是最常用的一个函数)

string& operator+= (const string& str);
string& operator+= (const char* s);
string& operator+= (char c);
void test13()
{
	string s1("hello");
	string s2("world");
	s1 += s2;
	cout << s1 << endl;

	s1 += "xxx";
	cout << s1 << endl;

	s1 += 'A';
	cout << s1 << endl;
}

结果如下: 

 ④c_str

const char* c_str() const;
void test14()
{
	string s("hello");
	//以语言的格式打印字符串
	cout << s.c_str() << endl;
}

结果如下:

 ⑤find函数

static const size_t npos = -1;//其实npos就是size_t的最大值

size_t find (const string& str, size_t pos = 0) const;
	
size_t find (const char* s, size_t pos = 0) const;
	
size_t find (const char* s, size_t pos, size_t n) const;
	
size_t find (char c, size_t pos = 0) const;
void test15()
{
	string s1("http://www.cplusplus.com/reference/string/string/find/");
	
	size_t pos1 = s1.find("com");//正向查找com字符串
	cout << pos1 << endl;

	string s2("http");
	size_t pos2 = s1.find(s2);//正向查找与s2对象匹配的字符串
	cout << pos2<< endl;

	size_t pos3 = s1.find('p');//正向查找字符p
	cout << pos3 << endl;
}

 结果展示:

 ⑥rfind

size_t rfind (const string& str, size_t pos = npos) const;
	
size_t rfind (const char* s, size_t pos = npos) const;

size_t rfind (const char* s, size_t pos, size_t n) const;
	
size_t rfind (char c, size_t pos = npos) const;
void test16()
{
	string s1("http://www.cplusplus.com/reference/string/string/find/");

	size_t pos1 = s1.rfind("string");//反向查找是s1中第一次出现的string的首位置
	cout << pos1 << endl;

	string s2("cplusplus");
	size_t pos2 = s1.rfind(s2);//反向查找s1中与s2对象匹配的首位置
	cout << pos2 << endl;

	size_t pos3 = s1.rfind('h'); //反向查找s1中h字符
	cout << pos3 << endl;
}

 结果展示:

⑦substr

string substr (size_t pos = 0, size_t len = npos) const;
void test17()
{
	//获取file的后缀
	string file("string.cpp");
	size_t pos = file.rfind('.');//反向查找 . 点
	string suffix(file.substr(pos,file.size()-pos));//从点开始,包括点的后面部分
	cout << suffix << endl;
}

结果:

5、string类非成员函数

函数

功能

operator+ 尽量少用,因为是传值返回,导致拷贝效率低
operator>> 流插入运算符重载
operator<< 流提取运算符重载
getline 获取一行字符串
relational operators 大小比较

输入输出问题: 

void test18()
{
	string s;
	cin >> s;//输入hello world
	cout << s << endl;//只会打印hello
}

 我们知道cin标准输入,当从键盘上面读取到空格或者\n时,会停止读取,这时候就要用到getline函数了

istream& getline (istream& is, string& str, char delim);
//从is中读取字符串,储存在str对象中,直到遇到delim界限符或者\n停止

istream& getline (istream& is, string& str);
//从is中读取字符串,储存在str对象中,直到遇到\n停止
void test18()
{
	string s1;
	getline(cin,s1,'e');//输入hello world
	cout << s1 << endl;//输出h
}
void test18
{
	string s2;
	getline(cin, s2);//输入hello world
	cout << s2 << endl;//输出hello world
}

大小比较问题:

void test19()
{
	string s1("hello");
	string s2("string");
	cout << (s1 > s2) << endl;//输出0
}

这里的有点不一样,比较的是第一个字符的ASCII码值的大小,若第一个相等则比较第二个,返回一个bool值,以此类推。

6、其他函数

做OJ题的时候比较常用

stoi——字符串转为整型

void test20()
{
	int val = stoi("12345");
	cout << val << endl;
}

还有很多类似的函数: stod stoll stof等等,感兴趣可以自行了解

to_string——其他类型转为字符串

void test21()
{
	string str = to_string(3.14);
	cout << str << endl;
}

谢谢观看!

猜你喜欢

转载自blog.csdn.net/weixin_57675461/article/details/123405293