2

假设我有一个这样的文件:

rotate -45
move 30

Whererotatemove是我写的两个函数。但我正在从文本文件中读取这些内容。

那么,我如何能够将这些用作我的程序的命令呢?

例如,我正在考虑使用strcmp. 所以我会将我读到的字符串与我所知道的可能的命令进行比较。然后,如果它们匹配,我想调用请求的函数。

我真的很想看一些示例代码来帮助理解。

感谢您的提示。所以使用 brunobeltran0 的第一种方法,我会这样做:

        char*next_command;
        char* get_next_command;g = fopen("b", "r");/*b is the name of the file*/

        while(!feof(g)) 
        {
        get_next_command=fgetc(g);

        next_command = strtok(get_next_command, " ");

         while (next_command != NULL) {

        printf("%s\n", next_command);

         next_command = strtok(NULL, " ");       

      if (!strcmp(next_command, "rotate")) 
        {   

        rotate (/*how would I get the number to be in here*/ )


         }`

这看起来不对。我错过了了解你们吗?

4

3 回答 3

2

我将假设您的意思是您要编写一个程序,给定一个包含它理解的命令的输入文件,从所述输入文件中读取并执行这些命令。根据你有多少命令,以及你对这些函数的格式的了解,周围的代码可能会有很大的不同,但在一般情况下,逻辑将类似于(忽略内存管理) )

char *next_command = get_next_command(...); // reading the commands is really specific to the input you expect
if (!strcmp(next_command, "some_command")) 
{
    void *param_arr[PARAM_CNT_FOR_SOME_COMMAND] = get_params_for_some_command(); 
    some_command(param_arr[0], param_arr[1], param_arr[2]); // assume some_command takes 3 arguments
}
else if (!strcmp(next_command, "some_other_command"))
...

例如,如果你想旋转 -45,

char *next_command = get_next_command(...); // reading the commands is really specific to the input you expect
if (!strcmp(next_command, "rotate")) 
{
    void *param_arr[1] = get_rotation_angle(); 
    rotate((int *)param_arr[0]); // assume some_command takes 3 arguments
}

应该管用。

如果您有可用的映射,那么从可能的输入命令映射到它们各自的函数并允许函数从文件本身读取以查找其参数可能会更有效。

例如:

char *next_command = get_next_command(file_pointer);
(*get_func_pointer(next_command))(file_pointer); // where get_func_pointer is a function that
                                                 // returns the function pointer assoc. with 'next_command'
/* somewhere else in the code */
void func_returned_by_get_func_pointer(FILE *fp)
{
    read_params_from(fp);
    do_everything_as_usual();
}
于 2012-10-01T09:21:44.790 回答
1

我会这样做:

  • 这些函数将被定义为采用可变数量的参数,除非它们都共享相同的函数签名,但名称除外。
  • 将函数名映射定义为指向函数定义指针的字符串。
  • 每次读取和解析一行时,函数名称将使用上面的映射解析为函数指针,并使用参数调用。

HTH。

于 2012-10-01T09:01:56.150 回答
0

尽量将解析器/调度代码与函数分离。这显示了适用于您的示例案例的调度程序示例:

typedef int (*Command)(double);
struct CommandEntry {
    const char *name;
    Command function;
};

int dispatch_commands(struct CommandEntry *commands, int num_commands,
                      const char *name, double param)
{
    /* loop over the arguments, look for a CommandEntry with a matching name,
       convert its parameter and then call it */
    int i;
    for (i = 0; i < num_commands; ++i) {
        if (!strcmp(commands[i].name, arg))
            return commands[i].*function(param);
    }
    return -1;
}

struct CommandEntry commands[] = {
    {"rotate", &my_rotate_func},
    {"move", &my_translate_func}
};

这假设所有命令都采用 type 的单个参数double,当然......如果你所有的命令都是同质的,你可以让它工作。否则,您需要指定每个参数的数量CommandEntry(并传递一个数组,因为函数类型仍然需要相同),或者为每个命令函数提供整个传入令牌流,并允许它作为许多令牌随心所欲。

于 2012-10-01T09:41:07.113 回答