我试图从一个文件中读取逻辑门名称和它们的输入。我得到了一个.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;
}
查询:,我应该如何修改我的代码,使它能够读取门的名称及其输入,而不管它们的位置是什么w.r.t白空间?
注意:--我必须只使用C++代码及其库来处理这个问题。
发布于 2014-05-12 13:17:01
您应该按照@Rook和@Klaus的建议,使用一个简单的xml文件,而不需要dtd和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方式
#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();
}
发布于 2014-05-12 13:06:32
第一个答案:永远不要自己编写手工解析器:-)
1)为像lex、yacc、bison这样的解析器使用代码生成器(更多.)
2)您可以从expect或regexp获得解析支持
3)寻找序列化,例如::序列化。如果修改编写器/读取器,则可以将其序列化为更复杂的格式,其中包含类似配置文件的内容。
如果您真的想编写自己的解析器,建议编写一个或多或少比较复杂的状态机。但这可以用工具来完成,比用手工要容易得多。
很抱歉,我不会深入研究您的代码,但我个人的经验是,它以大量的代码行结束,以获得一个真正的工作解析器。大多数情况下,代码不再是可维护的。因此,我建议您使用我提供的三个选项中的一个(或任何其他选项) :-)
https://stackoverflow.com/questions/23609574
复制相似问题