boost::string or boost::regex

boost::string or boost::regex

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

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

如果有一个文本文件,其包括内容类似于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 写了一个代码。 

#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 来写

#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] = '
#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; }
'; 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; }

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号