Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >boost::string or boost::regex

boost::string or boost::regex

作者头像
全栈程序员站长
发布于 2022-07-08 10:14:21
发布于 2022-07-08 10:14:21
2.2K00
代码可运行
举报
运行总次数:0
代码可运行

大家好,又见面了,我是全栈君。

有时候写代码时会遇到下面问题

如果有一个文本文件,其包括内容类似于C语言,当中有一行例如以下格式的语句:

layout (local_size_x = a,local_size_y = b, local_size_z = c) in;

当中用蓝色标记出的部分(layout, local_size_x, local_size_y, local_size_z, in)为keyword,斜体字部分(a, b, c)为数据类型为unsigned int的数字,请编写一个函数,用于从文件里抽取出a, b, c的值。当中文件名称为输入參数,该函数的返回值是抽取得到的a,b,c三个值。

比如。对于例如以下一个文本文件,程序期望的输出是(16, 16, 1)

#version 430 core layout (local_size_x = 16, local_size_y = 16, local_size_z = 1) in; void main(void) { imageStore(uTexture, ivec2(gl_GlobalInvocationID.xy), vec4(0, 0, 0, 0)); }

在分析文本时,须要注意例如以下几点:

a. 我们如果文本中有且仅仅有一个layout语句用于定义local_size_x。local_size_y和local_size_z。且这个语句的语法没有错误。

b. 用户能够通过//或者/*…*/方法来凝视掉某些代码。

c. 用户能够使用#define来进行宏定义;

d. local_size_x,local_size_y。local_size_z的默认值都为1,在定义了local_size_x和local_size_y的前提下。能够省略local_size_z;或者在定义了local_size_x的前提下,能够省略local_size_y和local_size_z。

比如。分析例如以下文本的返回值应该为(32, 16, 1)。

#version 430 core #define LOCAL_X32 // layout (local_size_x = 16, local_size_y = 13, local_size_z = 2) in; layout (local_size_x = LOCAL_X, local_size_y = 16) in; void main(void) { imageStore(uTexture, ivec2(gl_GlobalInvocationID.xy), vec4(0, 0, 0, 0)); }

用boost::string 写了一个代码。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <iostream>
#include <fstream>
#include <map>
#include <vector>
#include <boost/tuple/tuple.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/utility/string_ref.hpp>

class CTest
{
public:
	CTest(int vX = 1, int vY = 1, int vZ = 1) : m_X(vX), m_Y(vY), m_Z(vZ) {}
	~CTest() {}

//*********************************************************************************
//FUNCTION:
	void parseText(const char* vFileName)
	{
		std::vector<std::string> StrVec;
		preprocess(vFileName, StrVec);
		/*for (int i=0; i<StrVec.size(); ++i)
		{
			std::cout << StrVec[i] << std::endl;
		}*/
		processLayout(StrVec);
	}

//*********************************************************************************
//FUNCTION:
	void printMember() const
	{
		std::cout << m_X << " " << m_Y << " " << m_Z << std::endl;
	}

//*********************************************************************************
//FUNCTION:
	boost::tuples::tuple<int, int, int> getValue() const
	{
		return boost::make_tuple(m_X, m_Y, m_Z);
	}

private:
//*********************************************************************************
//FUNCTION:
	void preprocess(const char* vFileName, std::vector<std::string>& voStrVec)
	{
		std::ifstream Ifs(vFileName);
		if (!Ifs) 
		{
			std::cout << "Can not open the file " << vFileName << std::endl;
			exit(-1);
		}

		std::string LineStr;
		while (getline(Ifs, LineStr))
		{
			if (LineStr.find("//") != std::string::npos)
			{
				std::string::iterator End = LineStr.begin()+LineStr.find("//");
				if (LineStr.begin() != End) voStrVec.push_back(std::string(LineStr.begin(), End));
			}
			else if (LineStr.find("/*") != std::string::npos)
			{
				while (getline(Ifs, LineStr))
				{
					if (LineStr.find("*/") != std::string::npos) break;
				}
			}
			else if (LineStr.size() > 0) voStrVec.push_back(LineStr);
		}
		Ifs.close();
	}
//*********************************************************************************
//FUNCTION:
	void processLayout(const std::vector<std::string>& vStrVec)
	{
		std::map<std::string, int> DataMap;
		for (unsigned int i=0; i<vStrVec.size(); ++i)
		{
			if (vStrVec[i].find("#define") != std::string::npos) processDefine(vStrVec[i], DataMap);
			else if (vStrVec[i].find("layout") != std::string::npos) processLayout(vStrVec[i], DataMap);
		}
	}

//*********************************************************************************
//FUNCTION:
	void processDefine(const std::string& vSorceString, std::map<std::string, int>& voDataMap)
	{
		typedef boost::split_iterator<std::string::const_iterator> Split_String_Itearor;
		Split_String_Itearor Bgn, End;
		std::vector<std::string> StrVec;
		for (Bgn = boost::algorithm::make_split_iterator(vSorceString, boost::algorithm::token_finder(boost::is_any_of(" "))); Bgn != End; ++Bgn)
		{ 
			if ((*Bgn).size()>0) StrVec.push_back(std::string((*Bgn).begin(), (*Bgn).end()));
		}

		//for (int i=0; i<StrVec.size(); ++i)
		//{
		//	std::cout << StrVec[i] << std::endl;
		//}
		voDataMap[StrVec[1]] = boost::lexical_cast<int>(StrVec[2]);
	}

	void processLayout(const std::string& vSorceString, std::map<std::string, int>& vDataMap)
	{
		typedef boost::split_iterator<std::string::const_iterator> Split_String_Itearor;
		Split_String_Itearor Bgn, End;
		std::vector<std::string> StrVec;
		for (Bgn = boost::algorithm::make_split_iterator(vSorceString, boost::algorithm::token_finder(boost::is_any_of(" (,);="))); Bgn != End; ++Bgn)
		{ 
			if ((*Bgn).size()>0) StrVec.push_back(std::string((*Bgn).begin(), (*Bgn).end()));
		}

	/*	for (int i=0; i<StrVec.size(); ++i)
		{
			std::cout << "[" << StrVec[i] << "]";
		}std::cout << std::endl;*/

		if (StrVec.size() >= 4)
		{
			if (StrVec[2][0] >= '0' && StrVec[2][1] <= '9')
			{
				m_X = boost::lexical_cast<int>(StrVec[2]);
			}
			else
			{
				if (vDataMap.find(StrVec[2]) == vDataMap.end())
				{
					std::cout << "somethind if wrong \n";
					exit(1);
				}
				m_X = vDataMap[StrVec[2]];
			}
		}

		if (StrVec.size() >= 6)
		{
			if (StrVec[4][0] >= '0' && StrVec[4][0] <= '9')
			{
				m_Y = boost::lexical_cast<int>(StrVec[4]);
			}
			else
			{
				if (vDataMap.find(StrVec[4]) == vDataMap.end())
				{
					std::cout << "somethind if wrong \n";
					exit(1);
				}
				m_Y = vDataMap[StrVec[4]];
			}
		}

		if (StrVec.size() >= 8)
		{
			if (StrVec[6][0] >= '0' && StrVec[6][1] <= '9')
			{
				m_Z = boost::lexical_cast<int>(StrVec[6]);
			}
			else
			{
				if (vDataMap.find(StrVec[6]) == vDataMap.end())
				{
					std::cout << "somethind if wrong \n";
					exit(1);
				}
				m_Z = vDataMap[StrVec[6]];
			}
		}
	}

private:
	int m_X;
	int m_Y;
	int m_Z;
};

int main()
{
	CTest Test;
	Test.parseText("test.txt");
	Test. printMember();
	getchar();
	return 0;
}

只是这题能够用boost::regex 来写

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <string>
#include <fstream>
#include <iostream>
#include <boost\regex.hpp>
#include <boost\algorithm\string\split.hpp>
#include <boost\algorithm\string\regex.hpp>
#include <boost\algorithm\string\classification.hpp>

//****************************************************************************************************************
//FUNCTION:
unsigned int convertString2Ui(const std::string& vString)
{
	unsigned int Value = 0;
	for (unsigned int i=0; i<vString.length(); i++)
	{
		Value = Value*10 + vString.at(i)-'0';
	}

	return Value;
}

//****************************************************************************************************************
//FUNCTION:
void readContentFromFile(const char* vFileName, std::string& voContent)
{
	std::ifstream InFile(vFileName);
	char* pContent = NULL;
	if (InFile)
	{
		InFile.seekg(0, InFile.end);     
		unsigned int NumCharacter = unsigned int (InFile.tellg()); 
		pContent = new char[NumCharacter+1];
		InFile.seekg(0, std::ios::beg);
		int i=0;
		while (!InFile.eof())
		{
			if(InFile.read(&pContent[i], sizeof(char))) i++;	
		}
		pContent[i] = '\0';
		voContent = std::string(pContent);
	}	
	delete[] pContent;
}

//****************************************************************************************************************
//FUNCTION:
void deleteComments(std::string& vioString)
{
	boost::regex CommentRegEx("(//.*?\\n)|(/\\*.*?(\\*)+/)");
	vioString = boost::regex_replace(vioString, CommentRegEx, "", boost::regex_constants::match_not_dot_newline);
}

//****************************************************************************************************************
//FUNCTION:
void replaceMacro(std::string& vioString)
{
	boost::smatch MacroString;
	boost::regex  MacroRegex("^#define(\\s)+([a-zA-z_0-9\\(\\)]+)(\\s)+([a-zA-z_0-9\\(\\)]+)");
	std::string::const_iterator Start = vioString.begin();
	std::string::const_iterator End   = vioString.end();
	std::vector<std::string> MacroSet, ValueSet;
	while (boost::regex_search(Start, End, MacroString, MacroRegex, boost::regex_constants::match_not_null|boost::regex_constants::match_not_dot_newline))
	{
		Start = MacroString[0].second;
		MacroSet.push_back(MacroString[2].str());
		ValueSet.push_back(MacroString[4].str());
	}

	_ASSERT(MacroSet.size() == ValueSet.size());
	for (unsigned int i=0; i<MacroSet.size(); i++)
	{
		vioString = boost::regex_replace(vioString, boost::regex(MacroSet.at(i)), ValueSet.at(i));
	}
}

//****************************************************************************************************************
//FUNCTION:
void dumpNums(const std::string& vContent, unsigned int& voA, unsigned int& voB, unsigned int& voC)
{
	voA = voB = voC = 1;

	boost::regex MatchRegex("layout \\(local_size_x = ([0-9]+)(, local_size_y = ([0-9]+)(, local_size_z = ([0-9]+))?)?\\) in;");
	boost::smatch MatchString;
	boost::regex_search(vContent, MatchString, MatchRegex);
	voA = convertString2Ui(MatchString[1].str());	
	if (!MatchString[3].str().empty()) 
	{
		voB = convertString2Ui(MatchString[3].str());
		if (!MatchString[5].str().empty()) voC = convertString2Ui(MatchString[5].str());
	}
}

//****************************************************************************************************************
//FUNCTION:
void parseFile(const std::string& vFileName, unsigned int& voA, unsigned int& voB, unsigned int& voC)
{
	std::string Content;
	readContentFromFile(vFileName.c_str(), Content);	
	deleteComments(Content);
	replaceMacro(Content);
	dumpNums(Content, voA, voB ,voC);
}

void installMemoryLeakDetector()
{
#if defined(DEBUG) | defined(_DEBUG)
	_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
	//_crtBreakAlloc = 955;
#endif
}

int main(int argc, char** argv)
{
	installMemoryLeakDetector();

	_ASSERT(argc >= 2);
	const std::string FileName(argv[1]);
	unsigned int A = 0, B = 0, C = 0; 
	parseFile(FileName, A, B, C);
	std::cout << A << " " << B << " " << C << std::endl;

	return 0;
}

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/116016.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年1月2,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
C++教程(凯格尔训练法教程)
七种基本的C++数据类型:bool、char、int、float、double、void、wchar_t 类型修饰符:signed、unsigned、short、long 注:一些基本类型可以使用一个或多个类型修饰符进行修饰,比如:signed short int简写为short、signed long int 简写为long。
全栈程序员站长
2022/08/01
3K0
C++教程(凯格尔训练法教程)
1096. 地牢大师(BFS+三维数组)
地牢由若干个单位立方体组成,其中部分不含岩石障碍可以直接通过,部分包含岩石障碍无法通过。
浪漫主义狗
2022/07/11
3260
3 C++ Boost 字符,文本
3 C++ Boost 字符,文本 目录: 字符与数值转换 Boost format函数 简单实用 Boost format 输出人员信息 小案例 Boost format 数字处理 Boost format 高级特性 Boost String 处理,大小写转换 Boost String  字符串查找  Boost String 字符串判断式 Boost String 字符串替换: Boost String  字符串分割 Boost String trim剔除两边字符 Boost String  regex
py3study
2020/01/14
1.6K0
4.1 C++ Boost 字符串处理库
Boost 库是一个由C/C++语言的开发者创建并更新维护的开源类库,其提供了许多功能强大的程序库和工具,用于开发高质量、可移植、高效的C应用程序。Boost库可以作为标准C库的后备,通常被称为准标准库,是C标准化进程的重要开发引擎之一。使用Boost库可以加速C应用程序的开发过程,提高代码质量和性能,并且可以适用于多种不同的系统平台和编译器。Boost库已被广泛应用于许多不同领域的C++应用程序开发中,如网络应用程序、图像处理、数值计算、多线程应用程序和文件系统处理等。
王瑞MVP
2023/08/18
5400
运算符重载
流操作符>>,<<一般使用非成员函数实现,也就是友元函数实现,这样可以符合程序员的惯性思维
DeROy
2020/05/11
9990
4.5 C++ Boost 文件目录操作库
Boost 库是一个由C/C++语言的开发者创建并更新维护的开源类库,其提供了许多功能强大的程序库和工具,用于开发高质量、可移植、高效的C应用程序。Boost库可以作为标准C库的后备,通常被称为准标准库,是C标准化进程的重要开发引擎之一。使用Boost库可以加速C应用程序的开发过程,提高代码质量和性能,并且可以适用于多种不同的系统平台和编译器。Boost库已被广泛应用于许多不同领域的C++应用程序开发中,如网络应用程序、图像处理、数值计算、多线程应用程序和文件系统处理等。
王瑞MVP
2023/08/21
4200
4.7 C++ Boost 多线程并发库
Boost 库是一个由C/C++语言的开发者创建并更新维护的开源类库,其提供了许多功能强大的程序库和工具,用于开发高质量、可移植、高效的C应用程序。Boost库可以作为标准C库的后备,通常被称为准标准库,是C标准化进程的重要开发引擎之一。使用Boost库可以加速C应用程序的开发过程,提高代码质量和性能,并且可以适用于多种不同的系统平台和编译器。Boost库已被广泛应用于许多不同领域的C++应用程序开发中,如网络应用程序、图像处理、数值计算、多线程应用程序和文件系统处理等。
王瑞MVP
2023/08/21
7590
C++ Boost 文件系统相关函数
基础处理 #include <iostream> #include <boost/foreach.hpp> #include <boost/filesystem.hpp> using namespace std; using namespace boost; using namespace boost::filesystem; int main(int argc, char *argv[]) { // 判断路径是否为空 filesystem::path path_a; if (path_a.emp
王瑞MVP
2022/12/28
6620
C++字符串处理小结
常用的C++的字符串类型主要是std::string。它是模板std::basic_string的一个实例化。另外还有三个实例化std::wstring、std::u16string、std::u32string,不过不是很常用。
linjinhe
2018/06/06
3.1K3
19.11 Boost Asio 获取远程目录
远程目录列表的获取也是一种很常用的功能,通常在远程控制软件中都存在此类功能,实现此功能可以通过filesystem.hpp库中的directory_iterator迭代器来做,该迭代器用于遍历目录中的文件和子目录,它允许开发者轻松遍历目录层次结构并对遇到的文件和目录执行各种操作。
王瑞MVP
2023/11/09
1930
19.11 Boost Asio 获取远程目录
4.4 C++ Boost 数据集序列化库
Boost 库是一个由C/C++语言的开发者创建并更新维护的开源类库,其提供了许多功能强大的程序库和工具,用于开发高质量、可移植、高效的C应用程序。Boost库可以作为标准C库的后备,通常被称为准标准库,是C标准化进程的重要开发引擎之一。使用Boost库可以加速C应用程序的开发过程,提高代码质量和性能,并且可以适用于多种不同的系统平台和编译器。Boost库已被广泛应用于许多不同领域的C++应用程序开发中,如网络应用程序、图像处理、数值计算、多线程应用程序和文件系统处理等。
王瑞MVP
2023/08/21
5690
C++ Boost库 操作字符串与正则
字符串的查找与替换一直是C++的若是,运用Boost这个准标准库,将可以很好的弥补C++的不足,使针对字符串的操作更加容易。
王瑞MVP
2022/12/28
1.1K0
试试Boost.Asio
慢慢一点一点看看Boost,这段时间就Asio库吧。 据说这货和libevent的效率差不多,但是Boost的平台兼容性,你懂得。还有它帮忙干掉了很多线程安全和线程分发的事情。
owent
2018/08/01
4.1K0
【C++】开源:Boost网络库Asio配置使用
项目Github地址:https://github.com/boostorg/asio
DevFrank
2024/07/24
1.4K0
19.6 Boost Asio 文本压缩传输
Base64是一种二进制到文本的编码方案,用于将二进制数据转换为ASCII字符串格式。它通过将二进制数据流转换为一系列64个字符来工作,这些字符都可以安全地传输到设计用于处理文本数据的系统中。
王瑞MVP
2023/11/08
3130
19.6 Boost Asio 文本压缩传输
C++-入门语法(四)
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
cwl_java
2019/10/28
3090
4.2 C++ Boost 内存池管理库
Boost 库是一个由C/C++语言的开发者创建并更新维护的开源类库,其提供了许多功能强大的程序库和工具,用于开发高质量、可移植、高效的C应用程序。Boost库可以作为标准C库的后备,通常被称为准标准库,是C标准化进程的重要开发引擎之一。使用Boost库可以加速C应用程序的开发过程,提高代码质量和性能,并且可以适用于多种不同的系统平台和编译器。Boost库已被广泛应用于许多不同领域的C++应用程序开发中,如网络应用程序、图像处理、数值计算、多线程应用程序和文件系统处理等。
王瑞MVP
2023/08/18
1K0
Boost.Spirit 初体验
使用代码生成代码是一件十分美妙的事情,于是有了各种代码生成器。但是生成代码,意味着要有对生成规则的分析和处理。 Boost.Spirit 就是这么一个语法分析工具,它实现了对上下文无关文法的LL分析。支持EBNF(扩展巴科斯范式)。 Boost.Spirit 的使用真的是把模板嵌套用到了极致。确实这么做造成了非常强的扩展性,生成的代码也非常高效,但是嵌套的太复杂了,对于初学者而言真心难看懂。 你能想象在学习阶段一个不是太明白的错误导致编译器报出的几十层模板嵌套错误信息的感受吗?而且,这么复杂的模板嵌套还直接导致了编译速度的巨慢无比。 其实在之前,我已经使用过Spirit的Classic版本,即1.X版本,但是过多的复制操作让我觉得当时用得很低效,还好分析的内容并不复杂所以没。体现出来 这回就来研究下功能更强劲的2.X 版本。
owent
2018/08/01
3.4K0
C++入门-笔记(Cherno视频教程)
尽管 Python 简单易用,但在许多对实时性有较高要求的场景中,仍然需要使用到C++,例如在ROS系统开发、边缘设备部署,仍需依赖 C++。因此,本文主要作为入门和学习C++过程中的笔记博客,也希望对同样想学习C++的同学有所帮助。👓
Vaeeeee
2025/05/08
940
C++入门-笔记(Cherno视频教程)
C++ Boost库 操作日期与时间
Boost库中默认针对日期与时间的操作库分为,timer,progress_timer,date_time这几类,如下是一些常用的使用方法总结。
王瑞MVP
2022/12/28
1.7K0
相关推荐
C++教程(凯格尔训练法教程)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档