第12回 コーディング(3)(7月6日)

■ オリジナル機能の追加

今回からは、各自のオリジナル機能のコーディングを中心に行なう。

■ オプションの解析と処理の起動

プログラミングの参考資料を示す。

ソーティングの基準を、得点順、誕生日順、身長順など様々設けることができる。オプションのスイッチを入れることで、これらの機能を有効にすることが、コマンドラインを用いたプログラムの実行方法として用いられる。

例えば、「> ./prog SORT_BY_NAME」というオプションのときは、名前の ABC 順でソートし、「> ./prog SORT_BY_SCORE」というオプションのときは、得点順でソートするという実行方法である。

ところで、第5回の演習で、qsort を用いたソーティングを練習した。何を基準としてソートするのかは、比較関数の指定によりコントロールしていた。そのこと応用すると、オプション解析時に SORT_BY_NAME という指定であれば、たとえば、cmp_function1 という関数が比較関数として指定すればよく、SORT_BY_SCORE という指定であれば cmp_function2 という関数が比較関数として指定すれば良い。

具体的に、プログラムの骨組みを示す。
// 比較関数についての関数ポインタの型宣言
typedef int (* CmpFunc)(NameCard **, NameCard **);


// 総合得点による比較
int cmp_by_total_point(NameCard **nc1, NameCard **nc2)
{
  return nc_get_gp_total(*nc2) - nc_get_gp_total(*nc1);
}

// ドライバー番号による比較
int cmp_by_driver_number(NameCard **nc1, NameCard **nc2)
{
  return nc_get_driver_number(*nc1) - nc_get_driver_number(*nc2);
}


// オプション解析
void parse_options(char **argv, CmpFunc *ans)
{
  if( strcmp( argv[1], "SORT_BY_SCORE" ) == 0 )
    *ans = cmp_by_total_point;   // 関数名は、関数へのポインタを表す
  else if( strcmp( argv[1], "SORT_BY_NUMBER" ) == 0 )
    *ans = cmp_by_driver_number; // 関数名は、関数へのポインタを表す
  else
    *ans = NULL;
}


// メイン
int main(int argc, char **argv)
{
  CmpFunc cmp_func;
  NameCard **ncarray;

  parse_options( argv, &cmp_func );
  ncarray = make_name_card( - - - );
  qsort( ncarray, number_of_cards( ncarray ), sizeof(NameCard *), cmp_func );
  output_name_card( ncarray, - - - );
}


(c) Masato TOKUHISA (2007, July 2nd.)