有时候写代码时会遇到下面问题
如果有一个文本文件,其包括内容类似于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)); } |
#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;
}
#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] = '