在struct中使用typedef命名和索引文本命令 [英] Use typedef within struct for naming and indexing text commands

查看:140
本文介绍了在struct中使用typedef命名和索引文本命令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用一个简单的命令行应用程序,它接受ASCI文本并将其解释为命令。

I am working with a simple command line application that takes in ASCI text and interprets it as a command.

我试图通过 http://gcc.gnu.org/onlinedocs/cpp/Concatenation.html

例如:
考虑一个解释命名命令的C程序。可能需要一个命令表,可能是一个声明如下的结构数组:

eg: Consider a C program that interprets named commands. There probably needs to be a table of commands, perhaps an array of structures declared as follows:

 struct command
 {
   char *name;
   void (*function) (void);
 };

 struct command commands[] =
 {
   { "quit", quit_command },
   { "help", help_command },
   ...
 };

这将更清洁,不必给每个命令两次,一次在字符串常量和一次在函数名中。将命令的名称作为参数的宏可以使这不必要。可以使用字符串化创建字符串常量,并通过将参数与`_command'连接来创建函数名称。下面是如何完成的:

It would be cleaner not to have to give each command name twice, once in the string constant and once in the function name. A macro which takes the name of a command as an argument can make this unnecessary. The string constant can be created with stringification, and the function name by concatenating the argument with `_command'. Here is how it is done:

 #define COMMAND(NAME)  { #NAME, NAME ## _command }

 struct command commands[] =
 {
   COMMAND (quit),
   COMMAND (help),
   ...
 };

现在,假设我想要一个命令字符串和索引而非字符串和函数指针。

Now, let's say that I want to have a command string and index (ie: int) value, rather than a string and function pointer.

 struct command
 {
   char *name;
   int command_idx;
 };

现在,我有一种命名命令的方法,以编程方式识别每个命令。例如,我有一个switch语句,对命令索引进行操作。如果我想处理这些索引,我必须手动设置值。

Now, I have a means to name commands, and have some sort of index I can use later on to identify each command programatically. For example, I have a switch statement that operates on the command index. If I want to work on these indexes, I have to manually set the values first.

我可以手动创建一个枚举数据类型,但是我已经在一个单独的枚举语句中定义了枚举常量。 IE:
枚举命令{cmd_quit = 0,cmd_help}
,最后,我仍然需要输入两个命令名两次:一次通过COMMAND()宏,再次在我的枚举。

I can manually create an enumerated data type, but then I have define the enumerated constants in a separate enum statement. IE: enum commands { cmd_quit = 0, cmd_help } and in the end, I still end up having to type each command name twice: once via the COMMAND() macro, and again in my enum.

有没有任何方法使用C预处理器,允许我创建一个宏创建命令结构(带有字符串和int成员),并自动编号int value(command_idx)我通过COMMAND()宏添加更多的命令?

Is there any method using the C preprocessor that would allow me to create a macro creates the "command" struct (with string and int members), and auto-numbers the int value (command_idx) as I add more commands via the COMMAND() macro?

我也知道我可以只使用strcmp并与用户提供的输入进行比较,但我想有一个直接的方法通过command_idx值索引到命令,而不是strcmp'ing大量的命令每次(即:O(1)而不是的O(n))。我也想避免不得不多次输入命令名。

I am also aware that I can just use strcmp() calls on each possible command, and compare to the input provided by the user, but I would like to have a direct means of indexing into commands via the command_idx value, as opposed to strcmp'ing against a massive list of commands each time (ie: O(1) instead of O(n) ). I also want to avoid having to type the command name more than once at all costs.

谢谢!

推荐答案

您可以使用宏重定义来实现这一点。首先,创建一个简单列出您的命令 commands.inc 的文件:

You can use macro redefinition to achieve this. First, you create a file that simply lists your commands called commands.inc:

COMMAND(quit)
COMMAND(help)
...

然后,在您的C源中,您可以多次使用 COMMAND() #includecommands.inc c>有效地控制它是如何工作的。例如:

Then, in your C source you can #include "commands.inc" multiple times, with different definitions of COMMAND() in effect to control how it works. For example:

struct command
{
   char *name;
   int command_idx;
};

#define COMMAND(NAME) CMD_ ## NAME,

enum command_enum {
#include "commands.inc"
};

#undef COMMAND

#define COMMAND(NAME) { #NAME, CMD_ ## NAME },

struct command commands[] =
{
#include "commands.inc"
};

#undef COMMAND

(请注意,此特定示例依赖于C99改进,允许在枚举声明和复合初始化程序中的列表末尾的结尾在C89中,通过在结尾添加一个虚拟条目)。

(Note that this particular example relies on a C99 improvement that allows a trailing , at the end of the lists in the enum declaration and compound initialiser - you can easily work around that in C89 by adding a dummy entry at the end).

这篇关于在struct中使用typedef命名和索引文本命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆