首页 > 代码库 > 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)为关键字,斜体字部分(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)); } |
#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; }
#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 = http://www.mamicode.com/0;>