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

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

问题描述

我用一个简单的命令行应用程序,它发生在ASCI文字和跨$ P $点作为一个命令工作。

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

例如:
考虑到除$ P $点命名命令的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),
   ...
 };

现在,让我们说,我希望有一个命令字符串和索引(即:INT)值,而不是一个字符串函数指针

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}
而在最后,我还是最终不得不键入每个命令名称两次:在我的枚举通过命令()宏一次,然后再次

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 preprocessor,让我来创建一个宏创建命令结构(用绳子和int成员)自动编号​​的int值(command_idx)为我增加更多的方法,以及通过命令()宏命令?

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型,而不是O(1)(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源代码,你可以的#includecommands.inc多次,()命令的不同定义有效控制它是如何工作的。例如:

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).

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

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