我正在使用一个简单的命令行应用程序,它接收 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: 枚举命令 { cmd_quit = 0, cmd_help } 最后,我仍然不得不为每个命令名称输入两次:一次是通过 COMMAND() 宏,另一次是在我的枚举中。
是否有任何使用 C 预处理器的方法允许我创建一个宏来创建“命令”结构(具有字符串和 int 成员),并在我通过添加更多命令时自动编号 int 值 (command_idx) COMMAND() 宏?
我也知道我可以只对每个可能的命令使用 strcmp() 调用,并与用户提供的输入进行比较,但我想通过 command_idx 值直接索引命令,因为反对每次都针对大量命令进行 strcmp(即:O(1) 而不是 O(n) )。我还想不惜一切代价避免多次键入命令名称。
谢谢!
最佳答案
您可以使用宏重定义来实现这一点。首先,您创建一个名为 commands.inc
的文件,仅列出您的命令:
COMMAND(quit)
COMMAND(help)
...
然后,在您的 C 源代码中,您可以多次 #include "commands.inc"
,使用不同的 COMMAND()
定义来控制它的工作方式。例如:
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 改进,允许在 enum
声明和复合初始化程序中的列表末尾尾随 ,
- 您可以轻松地在 C89 中通过在末尾添加一个虚拟条目来解决这个问题。
关于c++ - 在结构中使用 typedef 来命名和索引文本命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7961217/