我正在尝试从文件中读取逻辑门名称及其输入。我收到了一个.bench
文件,其中提供了有关门名称及其输入的信息。
我在下面编写了一个代码,如果信息以下列格式给出,我会得到完美的结果:
firstGate = NAND(inpA, inpB, inpC)
secGate = NAND(1, 2)
30 = NAND(A, B)
问题:但是如果"白色空间发生变化"在=
签名之前,,
之后或其他地方,我的代码无效。对于
例如,如果文件以下列格式给出,那么我无法正确阅读
first=NAND(inpA, inpB, inpC) //no space before and after "="
sec = NAND(1,2) //no space after ","
我的代码适用于第一种情况如下:
int main(int argc, char* argv[])
{
//Reading the .bench file
ifstream input_file;
input_file.open("circuit.bench");
if(input_file.fail())
{
cout << "Failed to open Bench file.\n";
return 1;
}
///////
string line;
while (getline( input_file, line ))
{
///For NAND
size_t first_index_nand, second_index_nand;
string gate_name;
const string nand_str = "NAND(";
if ((first_index_nand = line.find(nand_str)) != string::npos)
{
gate_name = line.substr(0, first_index_nand - 3);
cout<<"\nGate name: "<<gate_name;
first_index_nand += nand_str.length() - 1;
cout<<"\nInput to this gate: ";
for (; first_index_nand != string::npos; first_index_nand = second_index_nand)
{
if ((second_index_nand = line.find_first_of(",)", first_index_nand)) != string::npos)
{
string input_name = line.substr(first_index_nand + 1, second_index_nand++ - first_index_nand - 1);
cout<<" "<<input_name;
}
}
}
cout<<"\n";
}
return 0;
}
查询:我应该如何修改我的代码,使其能够读取门的名称及其输入,而不管它们的位置是什么?空白?
注意:我必须使用C ++代码及其库来处理此问题。
答案 0 :(得分:1)
第一个答案:永远不要自己写一个手工解析器: - )
1)将代码生成器用于解析器,如lex,yacc,bison(更多......)
2)你可以从expect或regexp获得解析支持
3)寻找序列化,例如提高::序列化。如果您修改编写器/阅读器,则可以序列化为更复杂的格式,其中包含类似于配置文件的格式。
如果你真的想编写自己的解析器,那么大多数建议你编写一个或多或少复杂的状态机。但这可以通过工具更容易地手工完成。
Sorr,我不会深入研究你的代码,但我的个人经验是,它以大量代码行结束,以获得真正有效的解析器。而且大部分代码都不再可维护。所以我想建议你使用我提供的三个(或任何其他选项)中的一个: - )
答案 1 :(得分:0)
你应该像@Rook和@Klaus建议的那样,可能使用一个没有dtd的简单xml文件和一个像Xerces http://xerces.apache.org/xerces-c/这样的库。
如果您想使用文件格式,则应手动删除所有空格,例如,您可以在此处找到What's the best way to trim std::string?或此处:remove whitespace in std::string。 只有在那之后,您才能使用算法提取数据。
无论如何试试这应该有用。
#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>
using namespace std;
string trimWhiteSpaces(const string& line)
{
string l = line;
l.erase(std::remove_if( l.begin(), l.end(), ::isspace ), l.end());
return l;
}
int main(int argc, char* argv[])
{
cout << "starting... \n";
ifstream _ifile;
string fname = "gates.bench";
_ifile.open(fname.c_str());
if(!_ifile.is_open())
{
cerr << "Failed to open Bench file" << endl;
exit(1);
}
string line;
while(getline(_ifile, line))
{
line = trimWhiteSpaces(line);
size_t first_index_nand, second_index_nand;
string gate_name;
const string nand_str = "NAND(";
if ((first_index_nand = line.find(nand_str)) != string::npos)
{
gate_name = line.substr(0, first_index_nand - 3);
cout<<"\nGate name: "<<gate_name;
first_index_nand += nand_str.length() - 1;
cout<<"\nInput to this gate: ";
for (; first_index_nand != string::npos; first_index_nand = second_index_nand)
{
if ((second_index_nand = line.find_first_of(",)", first_index_nand)) != string::npos)
{
string input_name = line.substr(first_index_nand + 1, second_index_nand++ - first_index_nand - 1);
cout<<" "<<input_name;
}
}
}
cout<<"\n";
}
}
有更多OO approch
#include <iostream>
#include <fstream>
#include <string>
#include <algorithm>
using namespace std;
class FileParser
{
public:
FileParser (const string fname)
{
ifile.open(fname.c_str());
if(!ifile.is_open())
{
exit(1);
}
}
~FileParser()
{
ifile.close();
}
void Parse()
{
string line;
while(getline(ifile, line)){
line = trimWhiteSpaces(line);
size_t first_index_nand, second_index_nand;
string gate_name;
const string nand_str = "NAND(";
if ((first_index_nand = line.find(nand_str)) != string::npos)
{
gate_name = line.substr(0, first_index_nand - 3);
cout<<"\nGate name: "<<gate_name;
first_index_nand += nand_str.length() - 1;
cout<<"\nInput to this gate: ";
for (; first_index_nand != string::npos; first_index_nand = second_index_nand)
{
if ((second_index_nand = line.find_first_of(",)", first_index_nand)) != string::npos)
{
string input_name = line.substr(first_index_nand + 1, second_index_nand++ - first_index_nand - 1);
cout<<" "<<input_name;
}
}
}
cout<<"\n";
}
}
private:
string trimWhiteSpaces(const string& line)
{
string l = line;
l.erase(std::remove_if( l.begin(), l.end(), ::isspace ), l.end());
return l;
}
ifstream ifile;
};
int main(int argc, char* argv[])
{
FileParser fP("gates.bench");
fP.Parse();
}