Forgive me if this is somewhat basic.

If have an array of 20 strings defined:

char const commands[20][20] = {// each command string will have a maximum of 20 chars.
    "quit",
    "open",
    "save",
    "close"
};

I want to test the command value to see what action should be taken.

int in_array(char array[], char txt[], int len){
  for(int i=0;i<len;i++){
    if(txt==array[i][0]){
      return i;
    }
  }
  return -1;
}

What is the best way of doing this?

I am currently getting an error:
/home/dave/projects/fullpage/action.cpp:15:20: error: invalid types ‘char[int]’ for array subscript

I'd hapily use include <strings> but I get a similar error.

Why not use an enum class?

In C++ it is possible to create real enum types that are neither implicitly convertible to int and that neither have enumerator values of type int, but of the enum type itself, thus preserving type safety. They are declared with enum class (or enum struct) instead of just enum:

enum class Colors {black, blue, green, cyan, red, purple, yellow, white};

Each of the enumerator values of an enum class type needs to be scoped into its type (this is actually also possible with enum types, but it is only optional). For example:

Colors mycolor;

mycolor = Colors::blue;
if (mycolor == Colors::green) mycolor = Colors::red; 

You can read some more about this Here.

Why not use a std::list< std::string > to do this?

std::string has an operator== which you can use.

Depending on the situation you could use NathanOliver's solution. However, that requires you to know the entire set of commands at compile time. This may or may not be the case for you.

One way to do this in a somewhat dynamic way, is to use a map<string,function>. This allows you to run the appropriate routine depending on the string you get:

#include <iostream>
#include <map>

using namespace std;

typedef void(*CommandFunction) ();
void open()
{
    //code here
}
void close()
{
    //code here
}
void save()
{
    //code here
}
void quit()
{
    //code here
}
int main()
{
    map<string, CommandFunction> functions
    {
        {
            { "open", open },
            { "close", close },
            { "save", save },
            { "quit", quit }
        }
    };

    //command string
    string command = "open";

    //verify command and run the function
    if (functions.find(command) != functions.end())
        functions[command]();

    return 0;
}

You can have any combination of parameters and return types as long as each function is consistent. One trick you can use is to give default values to parameters a function won't use. This keeps their prototype the same.

Using this becomes very easy to maintain. Add/Remove a function, then update the map.

Edited 2 Years Ago by tinstaafl

Comments
This seems like the most efficient way.

Can't find much on std::list.

Google just gives a lot of pages on venereal disease. :(

Surely looking for an occurence of a string in an array of string is not an unusual operation?

For an example using strings and arrays and searching through the array.

//...

const int arraySize = 20;
char string commands[arraySize] = {"quit", "open", "save", "close"};
string command = "save";
cout << in_array(commands, command, arraySize);

//...

int in_array(const string commands[], cont string command, cont int arraySize)
{
    for(int i=0;i<arraySize;i++)
    {
        if(txt==array[i])
        {
          return i;
        }
    }
    return -1;
}

You can get information on std::list here. This site contains a lot of good reference material on the STL.

This article has been dead for over six months. Start a new discussion instead.