• 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 
    ";
    					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 
    ";
    					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 
    ";
    					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
    egex.hpp>
    #include <boostalgorithmstringsplit.hpp>
    #include <boostalgorithmstring
    egex.hpp>
    #include <boostalgorithmstringclassification.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] = '';
    		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;
    }




  • 相关阅读:
    NFC技术:让Android自动打开网页
    NFC技术:让Android自动运行程序
    NFC技术:概述
    路由器端口映射实现外网访问本地服务器
    Java之MySql数据库链接
    最短路径之Dijkstra算法及实例分析
    各种排序算法的时间性能比较
    C#实现基于ffmpeg加虹软的人脸识别
    虹软SDK在nodejs中的集成
    Android 虹软2.0人脸识别,注册失败问题 分析synchronized的作用
  • 原文地址:https://www.cnblogs.com/yxwkf/p/5193768.html
Copyright © 2020-2023  润新知