「C++」string类(2)常用接口

目录

前言

string构造

string类对象的容器操作(capacity)

string类对象的修改操作(modifiers)

[string类对象的其他操作(string operations)](#string类对象的其他操作(string operations))

string类相关非成员函数

swap

getline

后记


前言

本篇我们将继续讲解string类的内容,本篇着重聚焦各个类型接口的使用和部分注意事项

先附上文档:string - C++ Reference

string构造

构造函数我们在string类第一篇中以有解释,需要请移步「C++」string类(1)-CSDN博客

string类对象的容器操作(capacity)

使用及注意点:

  1. size:返回字符串的有效字符长度;

    size和lenght效果相同,引入size是为了和其他容器保持接口保持一致,一般都使用size接口;

  2. resize:将有效字符的个数改成n个,n小于size时,保留前n个字符,n大于size时多出的空间用参数填充(默认为'\0')(VS2022)

  3. capacity:返回容量大小,不包含"\0",即表示有效空间大小

  4. reserve:为字符串预留空间,一般为扩容(申请改变空间)

    VS2022环境下:只有当reserve空间大于容量时扩容,不存在缩容的情况;

    g++4.8:除n比size()小的情况会将capacity()缩小到size()大小外,按照n值进行缩扩容

  5. clear:清空有效字符,容量不变

  6. empty:检测字符串是否为空,为空返回ture,否则返回false

​相关测试代码:

cpp 复制代码
void Text_StringCapacityFunc()
{
	//size length max_size
	
	string str1 = "hello world!";
	cout << str1.size() << endl;//返回\0之前的字符个数
	cout << str1.length() << endl;
	cout << str1.max_size() << endl;
	

	//capacity resize clear empty
	
	string str2 = "hello world!";
	str2.resize(8);
	//设定长度小于原本字符串长度时,字符串将被截断,但capacity保持不变;
	cout << str2 << endl;
	str2 = "hello world!";
	cout << str2 << endl;

	cout << "size:" << str2.size() << endl;
	cout << "capacity:" << str2.capacity() << endl;
	str2.resize(16);
	//设定字符串大于有效字符长度时,会用默认值\0代替
	
	cout << "size:" << str2.size() << endl;
	cout << "capacity:" << str2.capacity() << endl;
	cout << str2.empty() << endl << endl;

	//清除有效字符,不改变空间大小
	str2.clear();
	cout << str2.size() << endl;
	cout << str2.capacity() << endl;
	cout << str2.empty() << endl;
	

	//reserve
	
	string str3 = "string_reserve_testdoce";
	cout << "size:" << str3.size() << endl;
	cout << "capacity:" << str3.capacity() << endl;

	cout << "输入78停止循环" << endl;
	int i;
	do
	{
		cin >> i;
		str3.reserve(i);
		cout << ".reserve(" << i << ") after:" << endl;
		cout << "size:" << str3.size() << endl;
		cout << "capacity:" << str3.capacity() << endl;
	} while (i != 78);

	// shrink_to_fit缩小capacity到有效字符需要的最小值
	str3.shrink_to_fit();
	cout << "shrink_to_fit" << endl;
	cout << "size:" << str3.size() << endl;
	cout << "capacity:" << str3.capacity() << endl;
}

string类对象的修改操作(modifiers)

使用及注意点:

  1. 修改操作中最常用的为+=重载;

  2. append尾插时可以调整子字符串插入的子字符串的起始位置及插入长度(不指定子字符串的插入长度时参数缺省为npos(c++14));push_back只能插入一个字符;

  3. assign进行替换操作时,会完全覆盖掉原本的数据并放入参数内容;当参数字符串小于原字符串的capacity时,不会改变容量大小;当参数字符串大于原字符串的capacity时,会自动进行扩容操作;

  4. insert插入子字符串时,必须指定插入的起始位置;当容量不足时会自动扩容;

  5. erase删除时,指定删除的起始位置和删除长度,删除长度缺省npos;

  6. replace指定替换起始位置和长度,子字符串也可指定

  7. swap交换时,会将两个对象的所有成员包括指针指向都进行交换;

  8. pop_back只能删除一个字符;

相关测试代码:

cpp 复制代码
void StringModifiersFunc()
{

	string* str = new string("hello! have a nice day!");
	//cout << *str << endl;
	//*str1 += "xx";
	//cout << *str << endl;
	
	string& str1 = *str;
	//cout << str2;

	//  operator+=	\
		append		\
		push_back	\
		assgin		\
		insert		\
		erase		\
		repalce		\
		swap		\
		pop_bakc	

	//string str2 = "good day!";
	////str1.append(str2, 5);
	//str1.append(str2, 1, 5);//插入内容为str2的pos=1开始往后5个字符长度的内容
	////str1.append(str2);
	//cout << str1 << endl;

	//str1.push_back('z');
	////str1.push_back("z");//报错,只能插入字符;
	//cout << str1 << endl;
	
	//cout << str1 << endl;
	//cout << str1.size() << endl << str1.capacity() << endl;
	//str1.assign("zxt");
	////str1.assign("zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz");
	//cout << str1 << endl;
	//cout << str1.size() << endl << str1.capacity() << endl;
	//打印结果可看出,assign虽然会替换原本的数据,但不会改变capacity的大小;\
		当替换内容大于capacity容量时,会扩容;

	//string str2 = "good!zzzzzzzzzzzzz";
	////pos=0时,为头插
	//cout << str1.insert(0, str2) << endl;
	////cout << str1.insert(0,str2, 1, 2) << endl;
	//cout << "size:" << str1.size() << endl << "capacity:" << str1.capacity() << endl;

	////pos=str1.size()时,即为尾插
	//str1.insert(str1.size(), str2);
	////str1.insert(str1.size(), str2, 1, 2);
	//cout << str1 << endl;

	//str1.insert(0, 2, 'x');//插入字符时,可指定插入个数
	//cout << str1 << endl;
	
	//erase头删
	//cout << str1.erase(0) << endl;
	//cout << typeid(str1.erase(str1.begin())).name() << endl;
	//cout << str1 << endl;

	//string::iterator i = str1.erase(str1.begin());
	//cout << typeid(i).name() << endl;
	//cout << str1 << endl;

	//string str2 = "zzzzzzzzzzzzzzz";
	//cout << str1 << endl;
	//cout << str1.size() << endl << str1.capacity() << endl;
	//str1.replace(2, 3, str2);//pos=2位置开始,替换原字符串往后三个字符长度的内容为str2
	//cout << str1 << endl;
	//cout << str1.size() << endl << str1.capacity() << endl;
	//replace空间不足时会自动扩容

	//string str2 = "hello!";
	////swap交换两个对象的所有成员和指向
	//str1.swap(str2);

	cout << str1 << endl;
	str1.pop_back();
	cout << "pop_back after : \n" << str1 << endl;

	delete(str);
}

string类对象的其他操作(string operations)

  1. c_str:返回C格式的字符串;

  2. copy可将指定位置开始,一定长度的字符串复制到目标中;

  3. find从头开始查找一个字符或者字符串,并返回其下标位置;rfind为从后往前查找;没有查找到时返回npos

  4. find_first_of:返回调用对象包含在 参数字符串范围内的字符 的位置,同理find_last_of则为反向查找;find_first_not_of和find_last_not_of则为返回不包含字符;

  5. substr:获取指定位置开始的指定长度的子串:

    当获取位置到结束的长度都小于指定长度len时,默认取到最后一个有效字符

相关测试代码:

cpp 复制代码
void StringOperationsTest()
{
	//c_str 返回字符串指针
	//读取文件
	//string filename;
	//cin >> filename;
	//FILE* fout = fopen(filename.c_str(), "r");
	//char ch = fgetc(fout);
	//while (ch != EOF)
	//{
	//	cout << ch;
	//	ch = fgetc(fout);//fgetc()获取字符后会自动往后位移一位
	//}
	//fclose(fout);

	//string str1 = "hello world!";
	//cout << str1.c_str() << endl;
	//cout << str1.data();

	//char buffer[20];
	//std::string str("Test string...");
	//std::size_t length = str.copy(buffer, 6, 5);
	//buffer[length] = '\0';
	//std::cout << "buffer contains: " << buffer << '\n';

	//使用find和substr获取文件后缀名
	//string str1 = "7_21_string.cpp";
	//size_t pos = str1.find(".");
	//cout << "find \".\" opsition:" << pos << endl;
	//cout << "file type: " << str1.substr(pos) << endl;

	////当有多个后缀名时,使用rfind反向查找获取正确的pos和后缀名
	//string str2 = "7_21_string.cpp.zip";
	//size_t pos1 = str2.find(".");
	//cout << "find \".\" opsition:" << pos1 << endl;
	//cout << "file type: " << str2.substr(pos1) << endl;

	//size_t pos2 = str2.rfind(".");
	//cout << "find \".\" opsition:" << pos2 << endl;
	//cout << "file type: " << str2.substr(pos2) << endl;

	//使用find_first_of屏蔽指定字符
	//string str1("Please, replace the vowels in this sentence by asterisks.");
	//size_t pos = str1.find_first_of("abcd");
	//while (pos != string::npos)
	//{
	//	str1[pos] = '*';
	//	pos = str1.find_first_of("abcd", pos + 1);
	//}
	//cout << str1 << endl;

	//同理使用find_first_not_of
	string str1("Please, replace the vowels in this sentence by asterisks.");
	size_t pos = str1.find_first_not_of("abcd");
	while (pos != string::npos)
	{
		str1[pos] = '*';
		pos = str1.find_first_not_of("abcd", pos + 1);
	}
	cout << str1 << endl;

}

string类相关非成员函数

swap

swap重载了一个针对于string类型的函数,其逻辑是,会调用string类中的成员函数swap

库中的swap函数:

由库中swap函数模板的实现逻辑可以看出,若string直接使用这个swap会导致多次的深拷贝,消耗资源;所以swap实现了string类的特化版本,使其去调用string中的swap成员函数,直接交换两个对象的内容,而不是使用深拷贝;

getline

在使用cin进行输入时,默认将空格和换行作为输入的分隔符,当需要将这些字符也写入对象中时,使用getline

  • 当不指定getline的结束获取的字符时,将默认为换行'n';可以在第三个参数位指定作为界限的字符

后记

关于string类中的相关部分接口的讲解就到这里,文中没有提及或者不全的部分,大家可以查看文档来学习,我们下期再见

本期专栏:C++_海盗猫鸥的博客-CSDN博客

个人主页:海盗猫鸥-CSDN博客

相关推荐
m0_748248022 小时前
揭开 C++ vector 底层面纱:从三指针模型到手写完整实现
开发语言·c++·算法
序属秋秋秋2 小时前
《Linux系统编程之开发工具》【实战:倒计时 + 进度条】
linux·运维·服务器·c语言·c++·ubuntu·系统编程
yugi9878383 小时前
基于Qt框架开发多功能视频播放器
开发语言·qt
whm27773 小时前
Visual Basic 手工制作工具栏
开发语言·visual studio
wangqiaowq6 小时前
StarRocks安装部署测试
java·开发语言
缺点内向9 小时前
C#: 高效移动与删除Excel工作表
开发语言·c#·.net·excel
老前端的功夫10 小时前
Web应用的永生之术:PWA落地与实践深度指南
java·开发语言·前端·javascript·css·node.js
ᐇ95911 小时前
Java HashMap深度解析:数据结构、原理与实战指南
java·开发语言·数据结构
QT 小鲜肉11 小时前
【个人成长笔记】在 Linux 系统下撰写老化测试脚本以实现自动压测效果(亲测有效)
linux·开发语言·笔记·单片机·压力测试