分析示例文本文件并将其拆分
Parsing a sample text file and splitting it up
我试图浏览一个包含汇编指令的简单文本文件,它看起来像这个
TOP NOP
VAL INT 0
TAN LA 2,1
这只是一个小例子,所以我可以向你展示它是如何工作的。基本上,我将第一个标签放在标签中,然后第二个标签是NOP、INT和LA,并将它们放在操作码中。
之后,我将采用第一个参数(0和2),并将它们放置在arg1中。然而,这就是我的问题所在。对于我现有的代码,当我将参数放入字符串时,我得到的输出是这样的
TOP
0
2
很明显,我只想让最后两个成为唯一的,但我该如何做到这一点,让TOP不会在我的第一次争论中陷入困境?
#include <string>
#include <iostream>
#include <cstdlib>
#include <string.h>
#include <fstream>
#include <stdio.h>
using namespace std;
int main(int argc, char *argv[])
{
// If no extra file is provided then exit the program with error message
if (argc <= 1)
{
cout << "Correct Usage: " << argv[0] << " <Filename>" << endl;
exit (1);
}
// Array to hold the registers and initialize them all to zero
int registers [] = {0,0,0,0,0,0,0,0};
string memory [16000];
string Symtablelab[1000];
int Symtablepos[1000];
string line;
string label;
string opcode;
string arg1;
string arg2;
// Open the file that was input on the command line
ifstream myFile;
myFile.open(argv[1]);
if (!myFile.is_open())
{
cerr << "Cannot open the file." << endl;
}
int counter = 0;
int i = 0;
int j = 0;
while (getline(myFile, line, 'n'))
{
if (line[0] == '#')
{
continue;
}
if (line.length() == 0)
{
continue;
}
if (line[0] != 't' && line[0] != ' ')
{
string delimeters = "t ";
int current;
int next = -1;
current = next + 1;
next = line.find_first_of( delimeters, current);
label = line.substr( current, next - current );
Symtablelab[i] = label;
current = next + 1;
next = line.find_first_of(delimeters, current);
opcode = line.substr(current, next - current);
if (opcode != "WORDS" && opcode != "INT")
{
counter += 3;
}
if (opcode == "INT")
{
counter++;
}
delimeters = ", nt";
current = next + 1;
next = line.find_first_of(delimeters, current);
arg1 = line.substr(current, next-current);
cout << arg1<<endl;
i++;
}
}
使用这种技术有很多弱点,您根本不会检查任何结果。例如,当你说:
current = next + 1;
您应该已经知道,项目之间只有一个分隔符!否则,你应该绕过所有项目,当你说时
next = line.find_first_of(delimeters, current);
<something> = line.substr(current, next - current)
你应该确定find_first_of
找到了一些东西,否则它将返回-1,next - current
将是负的!
如果我想做这项工作,我使用regex
,来自std
或boost
,使用regex,这项任务很简单,只需使用:
std::matches m;
std::regex rx("\s*(\w+)\s+(\w+)(?:\s+(\d+)\s*(?:,(\d+))?)?");
if (std::regex_match(line, m, rx)) {
// we found a match here
string label = m.str(1);
string opcode = m.str(2);
string arg1 = m.str(3), arg2 = m.str(4)
}
问题是寻找每个后续单词的开头:current = next + 1
。您需要查找第一个非分隔符作为单词的开头,并在查找参数之前检查是否位于行的末尾。
添加调试信息后,我看到以下内容:
>> label: start=0 end=3 value="TOP"
>> opcode: start=4 end=4 value=""
>> label: start=0 end=3 value="VAL"
>> opcode: start=4 end=4 value=""
>> label: start=0 end=3 value="TAN"
>> opcode: start=4 end=4 value=""
这告诉我每次操作码的尝试都是在寻找另一个分隔符。
问题是,你只在单词后面增加一个,下一行.substr()会捕获分隔符。
在启动后的查找中,更改:
current = next + 1;
至:
current = line.find_first_not_of(delimeters, next + 1);
这允许它在任何和所有分隔符之后查找下一个单词的开头。
此外,您希望使参数的查找以剩余的行长度为条件,因此将其封装在if(next >0) { ... }
中。
这给了我,我的调试和你的原始输出(有条件):
>> label: start=0 end=3 value="TOP"
>> opcode: start=6 end=-1 value="NOP"
>> label: start=0 end=3 value="VAL"
>> opcode: start=6 end=9 value="INT"
>> arg1: start=10 end=-1 value="0"
0
>> label: start=0 end=3 value="TAN"
>> opcode: start=6 end=8 value="LA"
>> arg1: start=9 end=10 value="2"
2
从主循环中重新考虑你的解析/标记,这样你就可以专注于它们。您甚至可能想要获得cppunit(或类似的)来帮助您测试解析函数。在没有这样的情况下,它可以帮助您转到一个地方并插入调试信息,如:
cout << ">> " << whatIsBeingDebugged << ": " << start=" << current
<< " end=" << next << " value= "" << value << """ << endl;
制作一个强大的词法分析器和解析器是许多库(lex和yacc、flex和bison等)的主题,可以是正则表达式等其他库的应用,甚至是整个大学课程。这是工作。但是,只要有条理、彻底并孤立地测试工件,例如使用cppunit(或类似的)进行单元测试。
- 如何拆分文件中.txt字母并使用c ++使用数组进行扑克?
- C++(.cpp文件和.h文件)拆分代码并添加一个函数,提取 - 这很容易吗?
- 如何在拆分为多个文件的分层 SM 中退出子机器?(使用boost::MSM)
- 如何通过在逗号处拆分将文件读入 2D 列表
- 读取行文本文件,如果它得到逗号,则拆分
- 将 c++ 代码拆分为多个文件
- 从文件中逐块读取,然后逐行拆分测试
- 如何使用 c++ 逐行处理文本文件并将其参数拆分为变量?
- C++ 将类拆分为多个文件.当我指定类型时假定显式类型 int
- 如何将程序拆分为文件C 类
- 从文件中获取字符串并将其拆分
- C++强力球 - 文件拆分和错误(游戏类型)
- 按代码 c 拆分文件时出错
- 分析示例文本文件并将其拆分
- 如何将XML文件拆分为多个XML,以便每个新文件只包含原始文件中的一个文本节点
- 正在分析文本文件并从中拆分
- C++将代码拆分为多个文件的问题
- 在C++中拆分文件
- 拆分文件并将数据传递给其他类
- 在c++中拆分文件并将其重新组合