might also consider this approach which splits a multi word command (e.g. led 10 on) into "tokens" and a pass the array of tokens to a command without worrying about the # and types of arguments a cmd might need
output
processCmd: martha
tokenize: martha
d:
tokDisp:
0 martha
processCmd: tom 1 2 3
tokenize: tom 1 2 3
a:
tokDisp:
0 tom
1 1
2 2
3 3
processCmd: dick xyz
tokenize: dick xyz
b:
tokDisp:
0 dick
0 xyz
processCmd: harry 1 abc 2
tokenize: harry 1 abc 2
c:
tokDisp:
0 harry
1 1
0 abc
2 2
updated with comments
// multiword command processing
// split separate word/values (i.e. tokens) in command line
// search for cmd in command-table, cmds[], and execute if found
// test with example command lines
char s [90]; // for sprintf()
// -----------------------------------------------------------------------------
// arrays of tokens (char *) and corresponging values if numeric
// a token in one word of text/numeric
#define MAX_TOKS 10
char * toks [MAX_TOKS];
int vals [MAX_TOKS];
int nTok;
char buf [90]; // char buffer when input is const char
// -------------------------------------
// display the current arrays of tokens and values
void
tokDisp ()
{
Serial.println (" tokDisp:");
for (int n = 0; n < nTok; n++) {
sprintf (s, " %6d %s\n", vals [n], toks [n]);
Serial.print (s);
}
}
// -------------------------------------
// locate tokens in provide string, set ptrs in tokens
int
tokenize (
char *str )
{
nTok = 0;
sprintf (s, " tokenize: %s\n", str);
Serial.print (s);
strcpy (buf, str); // copy possible const char array into char array
// initially call strtok() with char array, subsequent calls are passed nul
// continue processing until nul token found
// attempt to translate all tokens into numberic value
for (toks [nTok] = strtok (buf, " "); toks [nTok]; ) {
vals [nTok] = atoi (toks [nTok]);
toks [++nTok] = strtok (NULL, " ");
}
return nTok;
}
// -----------------------------------------------------------------------------
// test command functions used to demonstrate processing
void a (char *toks [], int n) { Serial.print (" a:\n"); tokDisp (); }
void b (char *toks [], int n) { Serial.print (" b:\n"); tokDisp (); }
void c (char *toks [], int n) { Serial.print (" c:\n"); tokDisp (); }
void d (char *toks [], int n) { Serial.print (" d:\n"); tokDisp (); }
// -------------------------------------
// command table - function ptr and command string
struct Cmd {
void (*f) (char *tok [], int nTok);
const char *name;
}
cmds [] = { // table for above command functions
{ a, "tom" },
{ b, "dick" },
{ c, "harry" },
{ d, "martha" },
};
const int Ncmd = sizeof(cmds)/sizeof(Cmd);
// -------------------------------------
// tokenize command line and search for cmd, 1st token, in cmds []
void
processCmd (
char *buf )
{
sprintf (s, "\nprocessCmd: %s\n", buf);
Serial.print (s);
tokenize (buf);
for (int n = 0; n < Ncmd; n++) {
// execute cmd when found and return
if (! strcmp (cmds [n].name, toks [0])) {
cmds [n].f (toks, nTok);
return;
}
}
// only reached if cmd not found
sprintf (s, " processCmd: unknown cmd %s\n", toks [0]);
Serial.print (s);
}
// -----------------------------------------------------------------------------
// define test command lines
char *str [] = {
(char *)"martha",
(char *)"tom 1 2 3",
(char *)"dick xyz",
(char *)"harry 1 abc 2",
};
const int Nstr = 4;
void setup ()
{
Serial.begin (9600);
delay (200);
// process each test cmd line
for (int n = 0; n < Nstr; n++)
processCmd (str [n]);
}
void loop () { }