首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >从文件中读取字符串格式的信息

从文件中读取字符串格式的信息
EN

Stack Overflow用户
提问于 2014-05-12 12:51:06
回答 2查看 473关注 0票数 0

我试图从一个文件中读取逻辑门名称和它们的输入。我得到了一个.bench文件,它提供了有关门名及其输入的信息。--我在下面编写了一段代码,如果信息是以以下格式提供的,它将给我提供完美的结果:

代码语言:javascript
运行
复制
firstGate = NAND(inpA, inpB, inpC)
secGate = NAND(1, 2)
30 = NAND(A, B)

问题:,但是如果在=签名之前、,之后或其他地方之前的“空格”发生了更改,那么我的代码就无法工作。例如,如果文件是以下列格式提供的,那么我无法正确地读取它

代码语言:javascript
运行
复制
first=NAND(inpA, inpB, inpC) //no space before and after "="
sec = NAND(1,2) //no space after ","

我的第一种情况的代码如下所示:

代码语言:javascript
运行
复制
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++代码及其库来处理这个问题。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 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。只有在此之后,才能使用算法提取数据。

不管怎样,试试这个吧,它应该能用。

代码语言:javascript
运行
复制
#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方式

代码语言:javascript
运行
复制
  #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();
}
票数 0
EN

Stack Overflow用户

发布于 2014-05-12 13:06:32

第一个答案:永远不要自己编写手工解析器:-)

1)为像lex、yacc、bison这样的解析器使用代码生成器(更多.)

2)您可以从expect或regexp获得解析支持

3)寻找序列化,例如::序列化。如果修改编写器/读取器,则可以将其序列化为更复杂的格式,其中包含类似配置文件的内容。

如果您真的想编写自己的解析器,建议编写一个或多或少比较复杂的状态机。但这可以用工具来完成,比用手工要容易得多。

很抱歉,我不会深入研究您的代码,但我个人的经验是,它以大量的代码行结束,以获得一个真正的工作解析器。大多数情况下,代码不再是可维护的。因此,我建议您使用我提供的三个选项中的一个(或任何其他选项) :-)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23609574

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档