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

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);
            }
        }
    }
}

Edited 4 Years Ago by deceptikon

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

This question has already been answered. Start a new discussion instead.