2016-05-26 8 views
1

だから今、私はこのようになります定義された構造を有する:さまざまなフィールドを持つメッセージを解析し、フィールドに基づいてコマンドを実行する最も良い方法は何ですか?

typedef struct rec_msg { 
    uint8_t unit[4]; 
    uint8_t subdevice[4]; 
    uint8_t command[4]; 
    uint16_t data[3]; 
    uint16_t msg_id[1]; 
} rec_msg; 

を...と私は、構造体の文字配列を読み、それに基づいてコマンドを実行します。今私はこのようにしています。それを行うにはもっときれいな方法があるようです。

if (strncmp((const char *)message->unit, "blah", 3) == 0) 
    { 
    if (strncmp((const char *)message->subdevice, "syr", 3) == 0) 
    { 
     if (strncmp((const char *)message->command, "rem", 3) == 0) 
     { 
     // run some command 
     } 
     else if (strncmp((const char *)message->command, "dis", 3) == 0) 
     { 
     // run some command 
     } 
     else 
     { 
     DEBUG_PRINT("Message contains an improper command name"); 
     } 
    } 
    else if (strncmp((const char *)message->subdevice, "rot", 3) == 0) 
    { 
     if (strncmp((const char *)message->command, "rem", 3) == 0) 
     { 
     // run some command 
     } 
     else if (strncmp((const char *)message->command, "dis", 3) == 0) 
     { 
     // run some command 
     } 
     else 
     { 
     DEBUG_PRINT("Message contains an improper command name"); 
     } 
    } 
    else 
    { 
     DEBUG_PRINT("Message contains an improper subdevice name"); 
    } 
    } 
    else 
    { 
    DEBUG_PRINT("Message contains the wrong unit name"); 
    } 
} 
+0

_cleaner_はどういう意味ですか?マクロ? –

+0

私は、基本的に巨大なif/else if treeを作成するのはちょっとばかげているようです。 – z470

+0

まず構文解析を行い、構文解析されたコマンド/データで構造体を作成し、コマンドの/ caseを切り替えて実行します。 –

答えて

1

一般的な質問の明示的なコードではなく、タスクをステップに分割します。擬似コードが続きます。

3つの文字列のそれぞれについて、一致するテキストを数値に変換します。対応する列挙体を持つ文字列の配列を提案する。 (2下図)

enum unit_index { 
    unit_blah, 
    unit_N 
}; 

const char *unit_string[unit_N] = { 
    "blah" 
}; 

enum subdevice_index { 
    subdevice_syr, 
    subdevice_rot, 
    subdevice_N 
}; 

const char *subdevice_string[subdevice_N] = { 
    "syr" 
    "rot" 
}; 

がルックアップマッチング指数

unit_index unit = find_index(message->unit, unit_string, unit_N); 
if (unit >= unit_N) { 
    DEBUG_PRINT("Message contains the wrong unit name"); 
    return FAIL; 
} 

subdevice_index subdevice = find_index(message->subdevice, subdevice_string, subdevice_N); 
if (subdevice >= subdevice_N) { 
    DEBUG_PRINT("Message contains the wrong subdevice name"); 
    return FAIL; 
} 

// similar for command 

今コードは、3つのテキストフィールドに対応する3つのインデックスを有しています。

typedef struct { 
    enum unit_index  unit; 
    enum subdevice_index subdevice; 
    enum command_index command; 
    int (*func)(); 
} index2func; 

index2func[] = { 
    { unit_blah, subdevice_syr, command_dis, command_blah_syr_dis }, 
    { unit_blah, subdevice_rot, command_dis, command_blah_rot_dis }, 
    ... 
    { unit_blah, subdevice_rpt, command_rem, command_blah_rot_rem } 
}; 

は、インデックスの整合セットのテーブルをウォークし、コマンドを実行し、インデックスのテーブルと、対応するコマンドを作成します。

+0

ありがとう!完璧な答え! – z470

関連する問題