0

Is it possible to replace all of these "if, else if ..." with an array of function pointers in this example of code ?

  if (strncmp(buff, "ls\n", 3) == 0)
    my_ls();
  else if (strncmp(buff, "cd\n", 3) == 0)
    my_cd();
  else if (strncmp(buff, "user\n", 5) == 0)
    my_user();
  else if (strncmp(buff, "pwd\n", 4) == 0)
    my_pwd();
  else if (strncmp(buff, "quit\n", 5) == 0)
    my_quit();

I'm trying to get something like this :

void (*tab[5]) (void);

  tab[0] = &my_ls;
  tab[1] = &my_cd;
  tab[2] = &my_user;
  tab[3] = &my_pwd;
  tab[4] = &my_quit;
apgobert
  • 31
  • 6

3 Answers3

1

I created a code to illustrate what you wanted to do, because I it's pretty entertaining.

#include <stdio.h>
#include <string.h>

// your functions
void my_ls()  { puts("fun:my_ls")  ;}
void my_cd()  { puts("fun:my_cd")  ;}
void my_user(){ puts("fun:my_user");}
void my_pwd() { puts("fun:my_pwd") ;}
void my_quit(){ puts("fun:my_quit");}


int main(int argc, char const *argv[])
{
    char* buff="ls\n"; // the string you have to compare

    void (*tab[5]) (void)={my_ls,my_cd,my_user,my_pwd,my_quit};
    char *names[5]={"ls\n","cd\n","user\n","pwd\n","quit\n"};

    int i;
    for (i=0; i<5; i++)
    {
        if(strncmp(buff,names[i],strlen(names[i]) )==0){
            tab[i]();
            return 0;
        }
    }
    return 0;
}

There are other ways to write it. Actually my_function is the same as &my_function since a function name alone is converted to the adress of the function. Also tab[i]() is equivalent to (*tab[i])()... Those are weird behaviours but I think it's specified by C standard

yakoudbz
  • 903
  • 1
  • 6
  • 14
1

There's no problem with an array of function pointers, but you'd need to convert the sequence of boolean strncmp() results to a single index.

If the list is long, the hash table idea might be a winner. For compact, simple code and easy maintenance, I've used an array of structs:

typedef struct cmdtable_t
{
    void (*fptr)();
    unsigned char length
    char name[11];
} cmdtable_t, *pcmdtable_t;

cmd_table_t commands = {
    { my_ls,   2, "ls"},
    { my_cd,   2, "cd" },
    { my_user, 4, "user" },
    ...etc.
};

That could also be what a hash table entry looks like, could be sorted in advance to allow a binary search, or simply sequentially searched for a KISS version until you find out whether this needs optimizing at all.

Mike Housky
  • 3,959
  • 1
  • 17
  • 31
0

I think you want a dictionary or hashtable:

  • Use buff as string key
  • Use function pointer as values
n0p
  • 3,399
  • 2
  • 29
  • 50
  • hash table or dictionary will be slower then known offset function call. But it will be much faster the individual strncmp. – cerkiewny Mar 24 '15 at 16:20