Hi all,

I've browsed the net trying to find a paradigm to describe what I'm looking for but haven't been successful. So I'll try to explain it as succinctly as I can.

Right now, for my PhD research, I've set out a few applications that take input files that have paramater/value pairs. When I want to execute a specific case, I generate a new text file with the input parameters I want to pass to the application and execute the application using these parameters.

Within the application, I read in the input file, strip and trim all unncessary stuff, like comment lines, whitespaces etc., and then I tokenize the contents and store the data on a line-by-line basis in a vector of strings. Then, for each tokenized line, I walk through a huge list of if-statements, to determine which parameter it is, and to subsequently set the value of the parameter in a struct, which I then use in the rest of my application.

Initially, this was a quick and dirty way to do this, and worked well, but it's turning out to be quite unwieldy now with all the if-statements. I'm sure there must be more intelligent ways of doing this.

What I'm basically looking for is a way to set up some sort of dictionary, that I can search through to match parameters from the input file, and then set the values given in the struct. Also, it would be handy if I can specify in the definition of the parameter in such a dictionary, what type of parameter/value combination it is, e.g., defining the data type and whether it's scalar/vector/list data.

From what I understand XML is appropriate for defining some of this, but I'm not very familiar with that, and before I take the plunge to look into something in further depth, I thought I'd ask here to see if someone can point me in the direction of any literature online that tackles input file parsing of parameter/value pairs.

Thanks in advance for your advice!

Regards,

Kartik

Recommended Answers

All 3 Replies

One way to avoid all those if statements is to set up an array of function pointers and parameter strings, then you can use a loop to iterate through the array to match the input parameters with the parameter strings in the array's structure. If the structures are in sorted order then you could use a binary search algorithm to find the function you want, or put the strings in a binary tree for searching.

Initially, this was a quick and dirty way to do this, and worked well, but it's turning out to be quite unwieldy now with all the if-statements. I'm sure there must be more intelligent ways of doing this.

It's funny that right as I hit the "huge list of if-statements" part of your description, my first thought was: why not a table driven approach? That's not always suitable depending on the complexity of your processing logic for each parameter, but it's generally superior in maintanability to a long chain of if statements or a switch statement with umpteen cases:

#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>

using namespace std;

struct Action
{
    string parameter;
    string value;

    Action(string const& init)
    {
        istringstream iss(init);

        // Error checking omitted for brevity
        iss >> parameter;
        iss >> value;
    }
};

// Set up desired actions
//
void Add(string const& value) { cout << "Adding '" << value << "'" << endl; }
void Modify(string const& value) { cout << "Modifying '" << value << "'" << endl; }
void Delete(string const& value) { cout << "Deleting '" << value << "'" << endl; }

// Set up a table of actions and conditions
//
struct ActionLookup
{
    const char* parameter;
    void (*run)(string const&);
};

ActionLookup lookup[] =
{
    {"add",    &Add},
    {"modify", &Modify},
    {"delete", &Delete},
};

const int nLookup = sizeof lookup / sizeof *lookup;

int main()
{
    ifstream in("test.txt");
    string line;

    while (getline(in, line))
    {
        Action action(line);

        // Find the appropriate action and run it
        for (int i = 0; i < nLookup; ++i)
        {
            if (lookup[i].parameter == action.parameter)
            {
                lookup[i].run(action.value);
            }
        }
    }
}

Great! Thank you for your feedback. I played around with the code a bit and the actions I've written now are:

storeStringValue, storeDoubleValue, storeIntegerValue

These actions all store the value of the input parameter in maps in a data container struct that I've created.

Now I can generalize the actions and the data container for the various input files I have, and also implement an action to parse a list of values too :).

Thanks again!

Kartik

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.