参数解析之写入参数解析

参数解析之写入参数解析

         之前我们有篇关于参数解析的文章《参数解析》,在文章中我们讨论了对函数参数进行了解析,分为两种方法:状态转换图和顺序扫描。函数参数为一个字符串,格式为:

file1|dataitem1|dataitem2|dateitem3|$file2|dataitem4|dataitem5|$file3|dataitem6|$

         通过我们的解析得到:

                                               file1 dataitem1 dataitem2 dataitem3

                                               file2 dataitem4 dataitem5

                                               file3 dataitem6

         这里的参数解析是针对read函数的参数解析,read函数根据输入参数的格式,读取相应的文件和字段,然后由输出参数将读取到的数据返回。输出参数的格式与输入参数的格式一致,即:file1|dataitem1的数据|dataitem2的数据|dataitem3的数据|$file2|dataitem4的数据|dataitem5的数据|$file3|dataitem6的数据|$。

         上面是针对read函数的参数解析,对于write函数来说,参数解析不仅仅需要解析要write的文件和字段,而且还要将待write数据解析出来。

         write文件和字段的格式与read函数的输入参数格式一致,即:file1|dataitem1|dataitem2|dateitem3|$file2|dataitem4|dataitem5|$file3|dataitem6|$,待write数据的格式为:dataitem1的数据|dataitem2的数据|dateitem3的数据|$dataitem4的数据|dataitem5的数据|$dataitem6的数据|$。所以,我们对write函数的参数解析需要解析以上两个参数。

         下面我们给出实现的程序:

// write函数参数解析

#include <iostream>

#include <string>

#include <vector>

using namespace std;



struct FileDataItems

{

    string file;

    vector<string> dataItems;

};



void ParaAnalysis_Items(const string& para, vector<FileDataItems>& fdis)

{

    fdis.clear();

    string file, data;

    FileDataItems fdi;

    int state = 1;

    for (auto i = 0; i < para.size(); ++i)

    {

        switch (state)

        {

        case 1:

            if (para[i] == '|')

            {

                fdi.file = file;

                fdis.push_back(fdi);



                state = 2;

            }

            else

            {

                file += para[i];

            }

            break;



        case 2:

            if (para[i] == '|')

            {

                fdis[fdis.size() - 1].dataItems.push_back(data);

                data.clear();

            }

            else if (para[i] == '$')

            {

                file.clear();

                state = 1;

            }

            else

            {

                data += para[i];

            }

            break;

        }

    }

}



void Write_ParaAnalysis(const string& fileDataItem, vector<FileDataItems>& fdis, const string& srcStr, vector<string>& srcData)

{

    fdis.clear();

    srcData.clear();



    ParaAnalysis_Items(fileDataItem, fdis);



    string dataItem;

    for (auto i = 0; i != srcStr.size(); ++i)

    {

        switch (srcStr[i])

        {

        case '|':

            srcData.push_back(dataItem);

            dataItem.clear();

            break;



        case '$':

            dataItem.clear();

            break;



        default:

            dataItem += srcStr[i];

            break;

        }

    }

}



int main()

{

    vector<FileDataItems> fdis;

    vector<string> srcData;



    int idx = 0;

    Write_ParaAnalysis("file1|dataitem1|dataitem2|dateitem3|$file2|dataitem4|dataitem5|$file3|dataitem6|$",

                        fdis,

                       "dataitem1的数据|dataitem2的数据|dateitem3的数据|$dataitem4的数据|dataitem5的数据|$dataitem6的数据|$",

                        srcData);



    for (auto i = 0; i != fdis.size(); ++i)

    {

        for (auto j = 0; j != fdis[i].dataItems.size() && idx != srcData.size(); ++j, ++idx)

        {

            cout << fdis[i].dataItems[j] << '\t' << srcData[idx] << endl;

        }

    }



    cout << endl;

    idx = 0;

    Write_ParaAnalysis("file1|dataitem3|dataitem2|dateitem1|$file2|dataitem5|dataitem4|$file3|dataitem6|$",

                        fdis,

                       "dataitem3的数据|dataitem2的数据|dateitem1的数据|$dataitem5的数据|dataitem4的数据|$dataitem6的数据|$",

                        srcData);

    for (auto i = 0; i != fdis.size(); ++i)

    {

        for (auto j = 0; j != fdis[i].dataItems.size() && idx != srcData.size(); ++j, ++idx)

        {

            cout << fdis[i].dataItems[j] << '\t' << srcData[idx] << endl;

        }

    }

    return 0;

}

参数解析之写入参数解析

         对于参数1的解析,我们还是沿用之前read函数的参数解析。对于参数2,我们顺序扫描,利用switch-case结构,检测当前字符,分为三种情况:’|’、’$’、其他,对不同的情况,进行相应的处理。

         对于参数1和参数2之间的匹配,我们是顺序匹配的,参数1的解析结果有文件结构。参数2的解析没有文件结构,而是顺序下来的。也就是说,我们没有对参数2进行文件结构的检测,这样如果参数2中的文件结构和参数1中的文件结构不一致,只要数据项个数一致,就没问题。这种情况,不是太符合我们的要求。如果参数2的文件结构和参数1的文件结构不一致,我们应该返回错误,而不是按照正确的情况进行处理。

         下面,我们给出检测参数2和参数1之间的文件结构是否一致的一种实现。对于参数1的解析依然沿用之前的解析方法。参数2的解析,不用到状态转换图来实现,而是对参数2进行顺序扫描,检测当前字符,根据当前字符的情况进行相应的处理。将参数1和参数2都解析完后,我们对两个参数中的文件结构进行匹配,如果匹配成功,则返回true,如果不成功,则返回false。下面是相应的程序实现:

// 检测参数1和参数2的文件结构是否一致

#include <iostream>

#include <string>

#include <vector>

using namespace std;



struct FileDataItems

{

    string file;

    vector<string> dataItems;

};



struct FileData

{

    vector<string> fData;

};



void ParaAnalysis_Items(const string& para, vector<FileDataItems>& fdis)

{

    fdis.clear();

    string file, data;

    FileDataItems fdi;

    int state = 1;

    for (auto i = 0; i < para.size(); ++i)

    {

        switch (state)

        {

        case 1:

            if (para[i] == '|')

            {

                fdi.file = file;

                fdis.push_back(fdi);



                state = 2;

            }

            else

            {

                file += para[i];

            }

            break;



        case 2:

            if (para[i] == '|')

            {

                fdis[fdis.size() - 1].dataItems.push_back(data);

                data.clear();

            }

            else if (para[i] == '$')

            {

                file.clear();

                state = 1;

            }

            else

            {

                data += para[i];

            }

            break;

        }

    }

}



void Para2Analysis(const string& srcStr, vector<string>& srcData)

{

    srcData.clear();

    string dataItem;

    for (auto i = 0; i != srcStr.size(); ++i)

    {

        switch (srcStr[i])

        {

        case '|':

            srcData.push_back(dataItem);

            dataItem.clear();

            break;



        case '$':

            dataItem.clear();

            break;



        default:

            dataItem += srcStr[i];

            break;

        }

    }

}



void Para2Analysis_File(const string& srcStr, vector<FileData>& srcData)

{

    srcData.clear();

    string datus;

    FileData fd;

    for (auto i = 0; i != srcStr.size(); ++i)

    {

        switch (srcStr[i])

        {

        case '|':

            fd.fData.push_back(datus);

            datus.clear();

            break;



        case '$':

            srcData.push_back(fd);

            fd.fData.clear();

            break;



        default:

            datus += srcStr[i];

            break;

        }

    }

}



void Write_ParaAnalysis(const string& fileDataItem, vector<FileDataItems>& fdis, const string& srcStr, vector<string>& srcData)

{

    fdis.clear();

    srcData.clear();



    ParaAnalysis_Items(fileDataItem, fdis);



    string dataItem;

    for (auto i = 0; i != srcStr.size(); ++i)

    {

        switch (srcStr[i])

        {

        case '|':

            srcData.push_back(dataItem);

            dataItem.clear();

            break;



        case '$':

            dataItem.clear();

            break;



        default:

            dataItem += srcStr[i];

            break;

        }

    }

}



void Write_ParaAnalysis_Func(const string& fileDataItem, vector<FileDataItems>& fdis, const string& srcStr, vector<string>& srcData)

{

    fdis.clear();

    srcData.clear();



    ParaAnalysis_Items(fileDataItem, fdis);



    Para2Analysis(srcStr, srcData);

}



void Write_ParaAnalysis_File(const string& fileDataItem, vector<FileDataItems>& fdis, const string& srcStr, vector<FileData>& srcData)

{

    fdis.clear();

    srcData.clear();



    ParaAnalysis_Items(fileDataItem, fdis);



    Para2Analysis_File(srcStr, srcData);

}



bool DetectFileStructure(const vector<FileDataItems>& fdis, const vector<FileData>& srcData)

{

    if (fdis.size() != srcData.size())

    {

        return false;

    }

    for (auto i = 0; i != fdis.size(); ++i)

    {

        if (fdis[i].dataItems.size() != srcData[i].fData.size())

        {

            return false;

        }

    }

    return true;

}



int main()

{

    vector<FileDataItems> fdis;

    vector<FileData> srcData;



    int idx = 0;

    Write_ParaAnalysis_File("file1|dataitem1|dataitem2|dateitem3|$file2|dataitem4|dataitem5|$file3|dataitem6|$",

                        fdis,

                       "dataitem1的数据|dataitem2的数据|dateitem3的数据|$dataitem4的数据|dataitem5的数据|$dataitem6的数据|$",

                        srcData);

    if (DetectFileStructure(fdis, srcData))

    {

        for (auto i = 0; i != fdis.size(); ++i)

        {

            for (auto j = 0; j != fdis[i].dataItems.size(); ++j)

            {

                cout << fdis[i].dataItems[j] << '\t' << srcData[i].fData[j] << endl;

            }

        }

    }

    else

    {

        cout << "参数1和参数2文件结构不匹配" << endl;

    }



    cout << endl;

    idx = 0;

    Write_ParaAnalysis_File("file1|dataitem3|dataitem2|dateitem1|$file2|dataitem5|dataitem4|$file3|dataitem6|$",

                        fdis,

                       "dataitem3的数据|dataitem2的数据|dateitem1的数据|$dataitem5的数据|dataitem4的数据|$dataitem6的数据|$",

                        srcData);

    if (DetectFileStructure(fdis, srcData))

    {

        for (auto i = 0; i != fdis.size(); ++i)

        {

            for (auto j = 0; j != fdis[i].dataItems.size(); ++j)

            {

                cout << fdis[i].dataItems[j] << '\t' << srcData[i].fData[j] << endl;

            }

        }

    }

    else

    {

        cout << "参数1和参数2文件结构不匹配" << endl;

    }



    cout << endl;

    idx = 0;

    Write_ParaAnalysis_File("file1|dataitem3|dataitem2|dateitem1|$file2|dataitem5|dataitem4|$file3|dataitem6|$",

        fdis,

        "dataitem3的数据|$dataitem2的数据|dateitem1的数据|$dataitem5的数据|dataitem4的数据|dataitem6的数据|$",

        srcData);

    if (DetectFileStructure(fdis, srcData))

    {

        for (auto i = 0; i != fdis.size(); ++i)

        {

            for (auto j = 0; j != fdis[i].dataItems.size(); ++j)

            {

                cout << fdis[i].dataItems[j] << '\t' << srcData[i].fData[j] << endl;

            }

        }

    }

    else

    {

        cout << "参数1和参数2文件结构不匹配" << endl;

    }

    return 0;

}

参数解析之写入参数解析

 

         总结

         本文我们对write函数的两个参数进行解析,先对参数2直接解析,并没有检测两个参数的文件结构是否一致;之后我们又对参数1和参数2的文件结构是否一致。

你可能感兴趣的:(解析)