程序最美(寻路)

你还在坚持练习你的技术吗?运动员天天训练,音乐家也会演练更难的曲章。你呢?

参数解析之写入参数解析

参数解析之写入参数解析

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

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的文件结构是否一致。

posted on 2013-10-09 23:20  unixfy  阅读(481)  评论(0编辑  收藏  举报

导航