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] = '\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;
}
boost::string or boost::regex的更多相关文章
- (四)boost库之正则表达式regex
(四)boost库之正则表达式regex 正则表达式可以为我们带来极大的方便,有了它,再也不用为此烦恼 头文件: #include <boost/regex.hpp> 1.完全匹配 std ...
- boost string algorithm
The Boost.StringAlgorithms library provides many free-standing functions for string manipulation. 1. ...
- boost::string 例题1
如果有一个语法正确的shader源文件,其包括若干关于uniform变量的定义.请写一个程序从某个shader源文件里提取其全部定义的uniform变量.要求记录其名称.数据类型和初始值(如果有定义) ...
- 一起学习Boost标准库--Boost.StringAlgorithms库
概述 在未使用Boost库时,使用STL的std::string处理一些字符串时,总是不顺手,特别是当用了C#/Python等语言后trim/split总要封装一个方法来处理.如果没有形成自己的com ...
- boost::tie()和boost::variant()解说
#include<iostream> #include<boost/tuple/tuple.hpp> #include<boost/variant.hpp> #in ...
- 字符串中判断存在的几种模式和效率(string.contains、string.IndexOf、Regex.Match)
通常情况下,我们判断一个字符串中是否存在某值常常会用string.contains,其实判断一个字符串中存在某值的方法有很多种,最常用的就是前述所说的string.contains,相对来说比较常用的 ...
- 以boost::function和boost:bind取代虚函数
转自:http://blog.csdn.net/Solstice/archive/2008/10/13/3066268.aspx 这是一篇比较情绪化的blog,中心思想是“继承就像一条贼船,上去就下不 ...
- [置顶] 编程模仿boost::function和boost::bind
boost::function和boost::bind结合使用是非常强大的,他可以将成员函数和非成员函数绑定对一个对象上,实现了类似C#的委托机制.委托在许多时候可以替代C++里面的继承,实现对象解耦 ...
- 用boost::bind构造boost::coroutine
class TestCoro { ... typedef boost::coroutines::coroutione<void ()> Coro; void CoroFun(Coro::c ...
随机推荐
- Eclipse+EGit的配置注意点, 以及解决Github多个本地仓库之间的冲突
问题描述 不同本地仓库(e.g. Repo1, Repo2)之间同时修改一个文件时, 出现文件无法merge的情况. 具体表现为, 冲突(红色双向实心箭头)一直存在, 点pull没反应, 点push报 ...
- 转载[WampServer下使用多端口访问]
作者:韩子迟 原文链接:http://www.cnblogs.com/zichi/p/4589142.html 注意点:www和www2都需要安装服务: 在C:\wamp\bin\apache\Apa ...
- 应该知道的Linux技巧
作者:陈皓(花名:钻风) 这篇文章来源于Quroa的一个问答<What are some time-saving tips that every Linux user should know?& ...
- 【LeetCode题意分析&解答】38. Count and Say
The count-and-say sequence is the sequence of integers beginning as follows:1, 11, 21, 1211, 111221, ...
- python 程序中设置环境变量
python 中调用系统命令有三种方法: 1.os.system('command') ,这个方法是直接调用标准C的system() 函数,仅仅在一个子终端运行系统命令,而不能获取命令执行后的返回信息 ...
- 把WinXP装进内存 性能飚升秒杀固态硬盘
现在用户新配置的电脑,内存很少有小于2GB的,配置4GB内存的朋友也有不少.容量如此大的内存,我们在使用电脑的日常操作中绝对用不完.而目前制约系统性能最大的瓶颈就是硬盘的传输速度,所以,这里教你怎么把 ...
- Windows 系统消息范围和前缀,以及消息大全
Windows系统定义的消息类别消息标识符前缀 消息分类ABM 应用桌面工具栏消息BM 按钮控件消息CB 组合框控件消息CBEM 扩展组合框控件消息CDM 通用对话框消息DBT 设备消息DL 拖曳列表 ...
- 深入浅出Win32多线程程序设计之基本概念
一.深入浅出Win32多线程程序设计之基本概念[转] 引言 从单进程单线程到多进程多线程是操作系统发展的一种必然趋势,当年的DOS系统属于单任务操作系统,最优秀的程序员也只能通过驻留内存的方式实现所谓 ...
- POJ 3061 Subsequence(Two Pointers)
[题目链接] http://poj.org/problem?id=3061 [题目大意] 给出S和一个长度为n的数列,问最短大于等于S的子区间的长度. [题解] 利用双指针获取每一个恰好大于等于S的子 ...
- 深度优先搜索算法(DFS)以及leetCode的subsets II
深度优先搜索算法(depth first search),是一个典型的图论算法.所遵循的搜索策略是尽可能“深”地去搜索一个图. 算法思想是: 对于新发现的顶点v,如果它有以点v为起点的未探测的边,则沿 ...