如何写一个简单的文件解析器?感觉是不是该用点什么模式?本帖最后由 elemusic 于 2012-12-13 21:58:19 编辑
如何写一个简单的文件解析器?感觉是不是该用点什么模式?
本帖最后由 elemusic 于 2012-12-13 21:58:19 编辑 没写过解析器,被这个头痛的东西搞晕了。
是一个分块的文件,每块有块标志,这个还好说,但是里面有子功能块,并且值和长度不固定,比较头痛。
以前没写过这种东西,写也就是写个简单的,有个块标志,有个长度的文件,无脑蛮干一下就提出来了。
这回这个头晕。
比如说发现9x标志(x为任意16进制数字),这个子功能块后面跟2字节,然后跟一个变长数字,然后后面可能又要跟
其他子块,比如说58 04标志的子块,后面跟4字节,还有别的子块,总之就是先要判断子块标志,再跟据标志读后面的字节数,并且中间还有可能插入不定长时间字节,不定长字节已经写了递归搞定了。
但是目前写得乱。
感觉蛮干写不太好,应该用点什么模式或者方法写个递归,几个函数就能搞定吧,不知道该怎么设计。
求大概思路。
整理一下说明,就是说有如下情况。
9x,后接2字节
Ax,后接3字节
Bx,后接4字节
Cx,后接1字节
51 03标志,后接3字节
58 04标志,后接4字节
其他标志,后接x字节
......
以上这些数字中间可能还插入不定长字节的时间记号。
该怎么设计,几个函数搞定呢?
[解决办法]
《编译原理》词法分析 有限状态自动机
[解决办法]
我将其每段都装入string中,希望对你有用.
//测试例子:51 03 00 00 41 42 43 58 05 00 00 00 31 32 33 34 35
#include<iostream>
#include<fstream>
#include<string>
#include<vector>
using namespace std;
int main(int argc, char *argv[])
{
ifstream ifile(argv[1],ios_base::binary);
vector<string> v;
char c;
while(ifile.get(c)) {
string s;
unsigned i,d;
switch (c) {
case '\x51':
s+= '\x51';
i=3;
break;
case '\x58':
s+= '\x58';
i=4;
break;
//加入你另外的处理,4字节不够可设另外的类型.
}
d=0;
for(unsigned int t=0; t<i; t++) {
ifile.get(c);
d = d
[解决办法]
(c << t*8);
s+=c;
}
char *up=new char[d];
ifile.read(up, d);
s.append(up,d);
v.push_back(s);
delete []up;
}
//输出之.
for(vector<string>::iterator j=v.begin(); j!=v.end(); ++j) {
for(string::iterator si=(*j).begin(); si!=(*j).end(); ++si) {
cout.width(2);
cout.fill('0');
cout << unsigned (*si) << ' ';
}
cout << endl;
}return 0;
}
