如果您在对特定字符串执行特定操作之后,这意味着您提前知道这些字符串。这反过来意味着它们的数量是有限的,是可数的,例如一组 N 个命令:
const char * commands[] = {
"command-1",
"command-2",
...
"command-N"
}
要使用 swtich 从您的代码中处理上述数组中的这些命令,您需要知道它们的索引,这很容易出错。所以给他们编号,给他们一个ID:
enum Command_id {
NO_COMMAND,
COMMAND_1,
COMMAND_2,
//...
COMMAND_N,
};
现在使用结构将上述两者放在一起:
struct Command_info {
const char * command;
enum Command_id id;
} command_infos[] = {
{"", NO_COMMAND},
{"command-1", COMMAND_1},
{"command-2", COMMAND_2},
// ...
{"command-N", COMMAND_N},
};
现在您有了很好的字符串及其相关 ID 的映射。为了能够在运行时从字符串映射到 ID,需要搜索上面的映射。要以有效的方式执行此操作,您需要使用二进制搜索。C 库证明bsearch()
了这一点。唯一的前提是要搜索的数组需要排序。
排序使用qsort()
也由 C 库证明。为了qsort()
工作,我们需要一个比较函数:
int cmp_command_infos(const void * pvCI1, const void* pvCI2)
{
const struct Command_info * pCI1 = pvCI1;
const struct Command_info * pCI2 = pvCI2;
return strcmp(pCI1->command, pCI2->command);
}
qsort()
像这样打电话
qsort(command_infos, sizeof command_infos / sizeof *command_infos, sizeof *command_infos, cmp_command_infos);
现在,由于数组已排序,因此可以使用bsearch()
. 对于“COMMAND-2”,它看起来像这样:
... = bsearch(&(struct Command_info){"COMMAND-2", NO_COMMAND}, command_infos, sizeof command_infos / sizeof *command_infos, sizeof *command_infos, cmp_command_infos);
将所有这些放在一起可能会导致:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
enum Command_id {
NO_COMMAND,
COMMAND_1,
COMMAND_2,
//...
COMMAND_N,
};
struct Command_info {
const char * command;
enum Command_id id;
} command_infos[] = {
{"", NO_COMMAND},
{"command-1", COMMAND_1},
{"command-2", COMMAND_2},
// ...
{"command-N", COMMAND_N},
};
int cmp_command_infos(const void * pvCI1, const void* pvCI2)
{
const struct Command_info * pCI1 = pvCI1;
const struct Command_info * pCI2 = pvCI2;
return strcmp(pCI1->command, pCI2->command);
}
int main(int argc, char ** argv)
{
qsort(command_infos, sizeof command_infos / sizeof *command_infos, sizeof *command_infos, cmp_command_infos);
{
enum Command_id command_id = NO_COMMAND;
struct Command_info * pCI = bsearch(&(struct Command_info){argv[1], NO_COMMAND}, command_infos, sizeof command_infos / sizeof *command_infos, sizeof *command_infos, cmp_command_infos);
if (NULL == pCI)
{
printf("Command = '%s' is unknown\n", argv[1]);
}
else
{
printf("Command = '%s' --> ID = %d\n", pCI->command, pCI->id);
switch(command_id)
{
case COMMAND_1:
/* perform action on COMMAND 1 here */
break;
case COMMAND_2:
/* perform action on COMMAND 1 here */
break;
default:
/* unknow command, do nothing */
break;
}
}
}
}
像这样称呼它:
./a.out command-1
给予:
Command = 'command-1' --> ID = 1
或者:
./a.out command-bla
给予:
Command = 'command-bla' is unknown
甚至
./a.out ""
给予:
Command = '' --> ID = 0