Я работаю с простым приложением командной строки, которое принимает текст ASCI и интерпретирует его как команду.
Я попытался минимизировать избыточность в этом приложении на примере http://gcc.gnu.org/onlinedocs/cpp/Concatenation.html.
например:
Рассмотрим программу на C, которая интерпретирует именованные команды. Вероятно, должна быть таблица команд, возможно, массив структур, объявленных следующим образом:
struct command
{
char *name;
void (*function) (void);
};
struct command commands[] =
{
{ "quit", quit_command },
{ "help", help_command },
...
};
Было бы лучше не указывать имя каждой команды дважды, один раз в строковой константе и один раз в имени функции. Макрос, который принимает имя команды в качестве аргумента, может сделать это ненужным. Строковую константу можно создать с помощью строкового преобразования, а имя функции - путем объединения аргумента с помощью `_command '. Вот как это делается:
#define COMMAND(NAME) { #NAME, NAME ## _command }
struct command commands[] =
{
COMMAND (quit),
COMMAND (help),
...
};
Теперь предположим, что я хочу иметь командную строку и значение индекса (то есть: int), а не строку и указатель на функцию.
struct command
{
char *name;
int command_idx;
};
Теперь у меня есть средство для именования команд, и у меня есть какой-то индекс, который я могу использовать позже для программной идентификации каждой команды. Например, у меня есть оператор switch, который работает с индексом команды. Если я хочу работать с этими индексами, я должен сначала вручную установить значения.
Я могу вручную создать перечислимый тип данных, но затем я определил перечислимые константы в отдельном операторе перечисления. IE:
команды enum {cmd_quit = 0, cmd_help}
и, в конце концов, мне все равно приходится вводить каждое имя команды дважды: один раз с помощью макроса COMMAND () и снова в моем перечислении.
Существует ли какой-либо метод, использующий препроцессор C, который позволил бы мне создать макрос, создает структуру "command" (с элементами string и int) и автоматически нумерует значение int (command_idx), когда я добавляю больше команд через КОМАНДА () макрос?
Мне также известно, что я могу просто использовать вызовы strcmp () для каждой возможной команды и сравнивать с вводом, предоставленным пользователем, но я хотел бы иметь прямое средство индексации команд с помощью значения command_idx, так как в отличие от strcmp'а против массивного списка команд каждый раз (то есть: O (1) вместо O (n)). Я также хочу избежать любой необходимости набирать имя команды более одного раза.
Спасибо!