c++ string(最终篇)

༺ 个人主页 · 纪念229 ༻

🏠我的博客主页🏠

༒专栏目录:《数据结构》༒

༒专栏目录:《算法》༒

༒专栏目录:《C++》༒

༒专栏目录:《MySQL数据库》༒

༒专栏目录:《前端开发》༒

༒其它有趣的计算机知识༒

༺世上本没有路,走的人多了自然就有了༻


本篇文章是C++string类讲解最后一篇,希望对你有所帮助


文章目录


1.findsuffix与split_url补充

这里是test_string10()代码应用的前提

c 复制代码
string findsuffix(const string& filename)
{
	size_t i = filename.rfind('.');
	//rfind(字符)从字符串尾开始找字符返回该字符下标
	if (i != string::npos)
	{
		return filename.substr(i);
		//cout << filename.substr(i);//这里是返回不是打印
		//substr(下标)返回下标指向的字符以及字符后面的有效字符
		//substr并不是将对象真的裁剪只是将要裁剪的部分返回
	}
	else
	{
		/*string empty;
		return empty;
		return string();*/
		return "";//""既可以装字符也可以装字符串
	}
}


//void split_url(const string& url)
//{
//	size_t i1 = url.find(':');
//	if (i1 != string::npos)
//	{
//		cout << url.substr(0, i1) << endl;
//	//substr(下表从哪开始,裁剪个数)这里裁剪的是下标为0以及下标i1 - 1之间的的字符串包括它们自己
//	}
//	
//	size_t i2 = i1 + 3;
//	//下标加几指的就是该数据之后的第几个位子(这里要越过//所以要到该字符第3个位置所以加3)
//	size_t i3 = url.find('/', i2);
//	if (i3 != string::npos)
//	{
//		cout << url.substr(i2, i3 - i2) << endl;//substr的第二个参数指的是要裁剪的个数(这里是i3 - i2(从i2开始截取的个数))
//		cout << url.substr(i3 + 1) << endl;
//		//下标和个数要分清
//	}
//	cout << endl;
//}

vector<string> split_url(const string& url)
//返回类型就是类(vector)
{
	vector<string> v;

	size_t i1 = url.find(':');
	if (i1 != string::npos)
	{
		v.push_back(url.substr(0, i1));
		//这里的v是vector<string>类型的字符数组它的push_back()和insert都可以插入字符串string类型insert()可以插入字符串push_back只能插入字符

	}

	size_t i2 = i1 + 3;
	size_t i3 = url.find('/', i2);
	if (i3 != string::npos)
	{
		v.push_back(url.substr(i2, i3 - i2));//i3 - i2截取的就是i2读过的个数
		//v.push_back(url.substr(i2, i3);//i3 - i2截取的就是i2读过的个数只写个i3不对
		v.push_back(url.substr(i3 + 1));
	}

	return v;
}

我们实例化一个vector类型的对象

size_t i1 = url.find(':');

我们先从url里找':'找到了就

v.push_back(url.substr(0, i1));这里从下标0开始查找获取个数为i其实就是截取从第一个字符开始到前面一个字符':'(string类里的substr(下标, 获取个数))

vector类型里的push_back(字符串)这里实际上就是将截取的字符串放入第一个元素中因为v里的数组没有数据

size_t i2 = i1 + 3;

因为这里:后面有//所以加3才可指向适合的位置

size_t i3 = url.find('/', i2);

然后我们继续找'/'找到了接着在v的第二个元素和第一个元素插入字符串(每插入一次其实就是一次构造函数)

v.push_back(url.substr(i2, i3 - i2));//i3 - i2截取的就是i2读过的个数

v.push_back(url.substr(i3 + 1));

我们如何确定第二个参数截取的个数呢?

其实就是从某下标开始找某个字符找到了返回个下标将原下标减去找到的下标其实就是我们我们所需要截取的个数(不包括':'要包括的话就将原下标与返回下标之差加1即可)

return v; 最后返回vector<string>类的对象 v


2.test_string9()

c 复制代码
void test_string9()
{
	//string s1("hello world");
	//string s2 = "hello world";

	string filename1("test.cpp");
	string filename2("test.c");
	string filename3("test");
	string filename4("test.cpp.tar.zip");
	cout << findsuffix(filename1) << endl;
	cout << findsuffix(filename2) << endl;
	cout << findsuffix(filename3) << endl;
	cout << findsuffix(filename4) << endl;

	string url1 = "https://qoder.cn/device/selectAccounts?challenge=rFt6hsDdRMQobUTGHYQSqiiGkujfj05EPiIrWgEvEZY&challenge_method=S256&client_id=732aef47-9cf2-46a2-95fe-4cebb5d0d1fa&machine_id=7d1ea9ea-8862-42b1-8622-52c38e1a912e&nonce=1e2a0c24-d160-48be-a879-0f9aade8182e&directLogin=true&directLogin=true";
	string url2 = "https://openlab.cosmoplat.com/lottery/16?inviteCode=25152";
	string url3 = "https://openlab.cosmoplat.com/2026programmer";

	/*split_url(url1);
	split_url(url2);
	split_url(url3);*/

	vector<string> ret = split_url(url1);
	//vector<string>是字符串数组每个元素都是字符串vector<char>是字符数组每个元素都是字符数组

		// string ip = dns_reuest(ret[1].c_str);
}

这里就是将找后缀和分割地址引用起来调试即可


3.test_stirng10()

c 复制代码
void test_string10()
{
	//std::string str("Please, replace the vowels in this sentence by asterisks.");
	//std::size_t found = str.find_first_not_of("aeiou");
	////find_first_not_of(字符集合)作用:从左往右找不属于字符集合("aeiou")的字符返回下标若是没找到返回string::npos
	//while (found != string::npos)
	//{
	//	str[found] = '*';
	//	found = str.find_first_not_of("aeiou", found + 1);
	//}
	////利用find_first_not_of()将不用的字符找出来将其替换(赋值)即可

	//cout << str << '\n';


	string s1("xxx");
	string s2("xxx11");
	const char* str = "232222";

	s1 == s2;
	s1 == str;
	str == s1;

	s1 + s2;
	s1 + str;
	str + s1;

	cin >> s1;
	cout << s1 << endl;

}

//int main()
//{
//	try
//	{
//		test_string10();
//	}
//	catch (const exception& e)//这里exception是因为没找到的话会报异常
//	{
//		cout << e.what() << endl;
//	}
//}
c 复制代码
//int main()
//{
//	try
//	{
//		test_string10();
//	}
//	catch (const exception& e)//这里exception是因为没找到的话会报异常
//	{
//		cout << e.what() << endl;
//	}
//}

当我们没找到时返回npos(异常)的检测

结构

c 复制代码
try
{
  test_string10();
}
catch(const exception& e)
{
  cout << e.what() << endl;
}

当test_string10()里抛异常catch就会接收到并且返回异常行(这里面是因为find()没找到对应字符抛异常)

c 复制代码
void test_string10()
{
	//std::string str("Please, replace the vowels in this sentence by asterisks.");
	//std::size_t found = str.find_first_not_of("aeiou");
	////find_first_not_of(字符集合)作用:从左往右找不属于字符集合("aeiou")的字符返回下标若是没找到返回string::npos
	//while (found != string::npos)
	//{
	//	str[found] = '*';
	//	found = str.find_first_not_of("aeiou", found + 1);
	//}
	////利用find_first_not_of()将不用的字符找出来将其替换(赋值)即可

	//cout << str << '\n';


	string s1("xxx");
	string s2("xxx11");
	const char* str = "232222";

	s1 == s2;
	s1 == str;
	str == s1;

	s1 + s2;
	s1 + str;
	str + s1;

	cin >> s1;
	cout << s1 << endl;

}

没注释的代码就不讲了就是类对象调用运算符重载

//std::size_t found = str.find_first_not_of("aeiou");

string类里的find_not_of(字符串)意思是将对象中除了字符串中的字符只要找到就返回下标没找到就返回string::npos静态常量(没找到)

c 复制代码
//while (found != string::npos)
//{
//	str[found] = '*';
//	found = str.find_first_not_of("aeiou", found + 1);
//}

找到了就将该位置赋值为'*'

然后found = str.find_first_not_of("aeiou", found + 1);find_first_not_of(字符串,下标)继续找不在字符串里的字符从下标的下一个位置开始找循环直到找不到为止

//cout << str << '\n';

最后返回修改后的str对象此时不会有字符串外的字符除了'*'


4.一些有关stirng的main函数

c 复制代码
//int main()
//{
//	string s;
//	//cin >> s;//这个读到空格就结束不适用
//	//getline(cin, s);//getline(cin,对象)读一行string头文件里的函数#include<iostream>里面不包含#include<string>
//	////
//	//size_t pos = s.rfind(' ');
//	//if (pos != string::npos)
//	//{
//	//	cout << s.size() - pos - 1 << endl;
//	//	//因为pos是下标所以要求剩余数目要将pos-1
//
//	//}
//	//else
//	//{
//	//	cout << s.size() << endl;
//	//}
//
//	getline(cin, s, '!');
//	//getline(cin, 对象, 到哪个字符停止读取)读取一行遇到指定字符停止读取遇到的该字符不会被读取(它是专门读字符串数组的函数)
//	cout << s << endl;
//}

这里就讲一个

// //getline(cin, s);//getline(cin,对象)读一行string头文件里的函数#include<iostream>里面不包含#include<string>

有时候我们会遇到要读取一行字符串的情况我们会遇到字符串里有空格我们就不能用cin >> 我们要用getline(cin,对象)getline是头文件#include里的函数不遇到'\n'读取就不会结束

// getline(cin, s, '!');//getline(cin, 对象, 遇到某个字符结束)之前第三个参数没写是就是默认第三个参数是'\n'

c 复制代码
//int main()
//{
//	//ctrl + Z结束while循环连续读取
//	string s;
//	while (cin >> s)
//	{
//		cout << s << endl;
//	}
//	return 0;
//}

这里就是在while里放cin >> X就可以连续读取按crel加c结束连续读取


5.isPalindrome

c 复制代码
//class Solution
//{
//public:
//	bool isLetterOrNumber(char ch)
//	{
//		return (ch == '0' && ch == '9')
//			|| (ch == 'a' && ch == 'z')
//			|| (ch == 'A' && ch == 'Z');
//	}
//
//	bool isPalindrome(string s)
//	{
//
//		for (auto e : s)
//		{
//			if (e >= 'a' && e <= 'z')
//			{
//				e -= 32;
//			}
//		}
//          size_t begin = 0, end = s.size() - 1;
//			while (begin < end)
//			{
//				//越过不是数字和字母字符的(遍历前提begin < end)
//				while (begin < end && !isLetterOrNumber(s[begin]))
//					begin++;
//				//while(begin < end && != isLetterOrNumber(s[behin]))这里不是字母、数字字符用的是!isLetterOrNumber(s.[begin])
//				while (begin < end && !isLetterOrNumber(s[end]))
//					end--;
//
//				//判断回文(判断两字符不相等判断相等无法说明)
//				if (s[begin] != s[end])
//				{
//					return false;
//				}
//				else
//				{
//					begin++;
//					end--;
//				}
//			}
//			//如果循环结束说明回环
//			return true;
// 
//	}
//
//
//};
//
////int main()
////{
////	Solution().isPalindrome("a");
////
////	return 0;
////}

这里就是判断是否为回文函数

c 复制代码
bool isLetterOrNumber(char ch)
//	{
//		return (ch == '0' && ch == '9')
//			|| (ch == 'a' && ch == 'z')
//			|| (ch == 'A' && ch == 'Z');
//	}

这里是判断是否是大小写英文字符或数字字符这里获取一个字符可以是三种情况可以是小写字符可以是大写字符也可以是数字字符所以这三种字符之间用||即可直接返回这三种情况

c 复制代码
//	bool isPalindrome(string s)
//	{
//
//		for (auto e : s)
//		{
//			if (e >= 'a' && e <= 'z')
//			{
//				e -= 32;
//			}
//		}
//          size_t begin = 0, end = s.size() - 1;
//			while (begin < end)
//			{
//				//越过不是数字和字母字符的(遍历前提begin < end)
//				while (begin < end && !isLetterOrNumber(s[begin]))
//					begin++;
//				//while(begin < end && != isLetterOrNumber(s[behin]))这里不是字母、数字字符用的是!isLetterOrNumber(s.[begin])
//				while (begin < end && !isLetterOrNumber(s[end]))
//					end--;
//
//				//判断回文(判断两字符不相等判断相等无法说明)
//				if (s[begin] != s[end])
//				{
//					return false;
//				}
//				else
//				{
//					begin++;
//					end--;
//				}
//			}
//			//如果循环结束说明回环
//			return true;
// 
//	}

判断回文的条件是从中心开始轴对称如果都相等的话就是回文字符串否则不是

我们用个范围for遍历所有字符串中的字符首先将大写字符变为小写字符 += 32

然后判断回文将左右两边比较是否相等

先用两个whlie()

c 复制代码
//越过不是数字和字母字符的(遍历前提begin < end)
//				while (begin < end && !isLetterOrNumber(s[begin]))
//					begin++;
//				//while(begin < end && != isLetterOrNumber(s[behin]))这里不是字母、数字字符用的是!isLetterOrNumber(s.[begin])
//				while (begin < end && !isLetterOrNumber(s[end]))
//					end--;

在begin < end的情况下左右两边若是遇到非数字字符与非字母字符的就左边加加或右边减减遇到是的就结束该方向的循环

然后判断左右两下标的字符是否相等相等就将将begin加加end减减继续循环判断若是不相等就返回false若是循环结束还是没问题就返回true说明是回文字符串


6.string类的底层复现(看我gitee代码里面有详细注释)

string类底层代码复现

Test.cpp只要从925开始复现

string.cpp和string.h都要复现

有序要的建议复现一下对我们用C++标准库里的string类有所帮助,我的注释不太好参考作用


文章到此就告一段落,希望对你有所帮助,感谢观看!

相关推荐
aqiu1111113 小时前
【C++算法打怪专栏】8. 字符串转换整数 (atoi)
开发语言·c++·算法
h39748 小时前
DirectShow过滤器开发-视频源过滤器
c++·windows·音视频·directshow
程序猿编码9 小时前
榨干 RTX5090 算力!Qwen3 专用单卡推理引擎,手写C++/CUDA 算子实现 MTP 推测解码
开发语言·c++·大模型推理·qwen3·多模态推理
西飘客10 小时前
vs 怎么根据dll 生成lib文件
c++·qt
aqi0010 小时前
鸿蒙版本的电子书阅读APP开放源码啦
android·华为·ai编程·harmonyos·鸿蒙
墨天梦10 小时前
B19_SunnyWeather到阅读客户端
android·kotlin
程序员老陆11 小时前
深入理解 C++ thread_local:线程私有存储的正确打开方式
开发语言·c++·程序设计
美狐美颜sdk11 小时前
直播APP源码可以直接接入视频美颜sdk吗?技术方案详解
android·人工智能·音视频·美颜sdk·直播美颜sdk
用户693717500138414 小时前
2026,程序员的时代拐点到了
android·前端·后端