In C, the fastest way to jump to a function from a user-defined input string

I take user input from a serial interface where they can write commands with arguments. I would like to know what is the fastest method for moving from a function to this input.

I saw this, but I don’t remember how it was implemented. I believe that he used a table of strings, each of which has a function pointer associated with it. Instead of using strcmp for each table element to match rows, is there a way I can “insert” an element into this table from this row input?

+4
source share
3 answers

XMacros, : http://www.drdobbs.com/the-new-c-x-macros/184401387

, :

#define COMMAND_FUNCTION_TBL \
#define _X(CMD_C, "copy", command_copy_handler)
#define _X(CMD_E, "exit", command_exit_handler)
...
#endif

// Enum
typedef enum {
#define _X(a,b,c) a,
COMMAND_FUNCTION_TBL
#undef _X
CMD_MAX
} CMD_ENUM_TYPE;


// String table
char command_string[CMD_MAX][] = { \
#define _X(a,b,c) b,
COMMAND_FUNCTION_TBL
#undef _X
}

// Function table
FUNC_PTR_TYPE command_function[CMD_MAX] = { \
#define _X(a,b,c) c,
COMMAND_FUNCTION_TBL
#undef _X
}

, - :

void command_dispatcher(char *command) {
   CMD_ENUM_TYPE i = 0;
   for (; i < CMD_MAX ; i++) {
        if (strcmp(command, command_string[i]) == 0) {
            command_function[i]();
            break;
        }
    }
}
+2

, , char string (char *).

, char switch == !=, strcmp strncmp

, - char :

char command;
int a1;
int a2;
int res;
printf("Entar a command for calcualation: ");
scanf("%d %c %d", &a1, &command, &a2);
switch (command)
{
case '+': res = a1 + a2;  // or res = add(a1, a2);
    break;
case '-': res = a1 - a2;
    break;
case '*': res = a1 * a2;
    break;
default: res = 0;
}
printf("Result is %d\n", res);

, :

// list of commands where last item is empty string
char commands[][20] = {"copy", "del", "compare", "clear",""};
char command[20];
char arg1[20];
char arg2[20];
printf("> ");
scanf("%s", command);
int commandID = 0;
// find what command was entered
while (commands[commandID][0] != '\0')
{
    if (!strcmp(commands[commandID], command))
        break; // stop the loop if command found
    commandID++;
}
if (commands[commandID][0] != '\0')
    printf("command ID is %d\n", commandID);
else
    printf("command is invalid\n");

, , ID - :

enum COM_ID{C_COPY, C_DEL, C_COMPARE, C_CLEAR, C_ERR};
char commands[][20] = {"copy", "del", "compare", "clear",""};

commandID switch, :

switch (commandID)
{
case C_COPY: 
    ask2args(arg1, arg2); // your implementation to read 2 strings from stdin 
    copy(arg1, arg2); // your implementation of copy command
    break;
case C_DEL:
    ask1arg(arg1);
    del(arg1);
    break;
case C_COMPARE:
    ask2args(arg1, arg2);
    compare(arg1, arg2);
    break;
case C_CLEAR:
    clear();
    break;
}

, , . , , .

,

void(*fucs[4]) (const char * a1, const char * a2);

fucs[commandID](arg1, arg2);
0

, .

, , . , .

LoseLose (hash = hash + character), , :

#include <stdio.h>
#include <stdlib.h>

void open() { puts("You choosed 'open'."); }
void copy() { puts("You choosed 'copy'."); }
void paste() { puts("You choosed 'paste'."); }

#define JUMP_TABLE \
    X(open, 'o' + 'p' + 'e' + 'n') \
    X(copy, 'c' + 'o' + 'p' + 'y') \
    X(paste, 'p' + 'a' + 's' + 't' + 'e')

int hash(const char *str) {
    int hash = 0, c;
    while(c = *str++) hash += c;
    return hash;
}

int main(int argc, char *argv[]) {
    if(argc < 2) {
        puts("Enter one of the following commands: 'open', 'copy' or 'paste'");
        exit(EXIT_FAILURE);
    }

    switch(hash(argv[1])) {
#define X(func, hash) case hash: func(); break;
    JUMP_TABLE
#undef X
    default: puts("Unknown command.");
    }
    return 0;
}

X Macros, . enum .

0

Source: https://habr.com/ru/post/1682377/


All Articles