2

次のようなファイルがあるとします。

rotate -45
move 30

私が書いた2つの関数はどこrotateにありますか。moveしかし、私はこれらをテキストファイルから読んでいます。

では、これらをプログラムのコマンドとしてどのように使用できるでしょうか。

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 に答える