0

I'm trying to build a serial command interpreter, so I want to store my commands in an array. I want each command to have a name and a function pointer so that I can compare the command name to what I typed into and then call the function. I'm not that good with C, so please help! Here is what I have so far.

The command array will be an array of structs. Each struct will have a string and a function pointer. There are errors here, but I don't know how to fix them. These are done before main.

typedef struct cmdStruct {
    char cmd[16];
    void (*cmdFuncPtr)(void);
}CmdStruct;

void (*ledFuncPtr)(void);
void (*cmd2FuncPtr)(void);

// assign pointers to functions
ledFuncPtr = &LedFunction;
cmd2FuncPtr = &Cmd2Function;

//build array of structs
CmdStruct cmdStructArray[] = cmdStructArray = { {"led",   ledFuncPtr   },
                                                {"cmd2",  cmd2FuncPtr  },  };

Later on, I will go through the struct array to compare it to the received command.

// go through the struct array to do string comparison on each struct's string member
for (int i = 0; i < sizeof(cmdStructArray); i++) {
    // string comparison of received command and string of struct
    if(strcmp(cmdStructArray[i].cmd, receivedCmd)==0) {
        // dereference function pointer
        (*cmdStructArray[i].cmdFuncPtr)(void);
    }
}

What parts am I doing wrong, and how do I fix them?

1
  • You are iterating i until sizeof(CmdStructArray) ie 16*sizeof(char) + size of a pointer(in your machine). which is definitely larger than in your case. Commented Jan 9, 2013 at 19:33

2 Answers 2

4

sizeof(cmdStructArray) is not in elements, but rather in bytes.

Use sizeof(cmdStructArray)/sizeof(cmdStructArray[0]).

Sign up to request clarification or add additional context in comments.

Comments

3

As it has already been noted, your cycle makes wrong number of iterations. sizeof array does give you the number of elements in the array, but rather the number of bytes in the array. You have to calculate sizeof array / sizeof *array to get the number of elements.

Also, your function call syntax is invalid

 (*cmdStructArray[i].cmdFuncPtr)(void);

The above will not compile. You cannot specify void as an argument in function call. (void) syntax can only be used in function declarations. If the function accepts no parameters, the call should look as

 (*cmdStructArray[i].cmdFuncPtr)();

Also, this will not compile as well

CmdStruct cmdStructArray[] = cmdStructArray = { {"led",   ledFuncPtr   },
                                                {"cmd2",  cmd2FuncPtr  },  };

Why are you mentioning cmdStructArray in this declaration twice?


Some additional, essentially cosmetic remarks:

Firstly, since your commands are probably going to be string literals known at compile time, you can declare the first member of your struct as a const char * pointer instead of char array

typedef struct cmdStruct {
  const char *cmd;
  void (*cmdFuncPtr)(void);
} CmdStruct;

The initialization syntax does not change. This will relieve you of the need to worry about the size of the array (16 that you currently have there).

Secondly, it is not clear why you had to declare intermediate pointers to functions ledFuncPtr and cmd2FuncPtr instead of initializing your array directly. What was the purpose of this

void (*ledFuncPtr)(void);
void (*cmd2FuncPtr)(void);

// assign pointers to functions
ledFuncPtr = &LedFunction;
cmd2FuncPtr = &Cmd2Function;

CmdStruct cmdStructArray[] = { {"led",   ledFuncPtr  },
                               {"cmd2",  cmd2FuncPtr }, };

when you could simply do this

CmdStruct cmdStructArray[] = { {"led",   &LedFunction  },
                               {"cmd2",  &Cmd2Function }, };

(without introducing ledFuncPtr and cmd2FuncPtr at all)?

Thirdly, you don't have to use * and & operators with function pointers. This will work too

CmdStruct cmdStructArray[] = { {"led",   LedFunction   },
                               {"cmd2",  Cmd2Function  }, };

and

cmdStructArray[i].cmdFuncPtr();

Anyway, this is a purely cosmetic issue, a matter of personal preference.

2 Comments

I'd like to add that CmdStruct cmdStructArray[] = cmdStructArray = { {"led", LedFunction }, {"cmd2", Cmd2Function }, }; i.e. double assignment is not legal in C. I'm also not sure what the original purpose of this double assignment is.
@user1294203: Yes, I missed this detail. Added to the answer. Thanks. In the OP's code the first = will probably be interpreted as initialization, while the second = - as assignment. However, the syntax of the right-hand side is invalid for assignment, not even mentioning that arrays are not assignable.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.