2

Cプログラムで2つのオプションを解析しようとしています。

プログラムは次のように呼び出されます。

./a.out [OPTIONS] [DIRECTORY 1] [DIRECTORY 2]

プログラムは2つのディレクトリを同期し、2つのオプションがあります。(-r)再帰的な同期(フォルダ内のフォルダ)、および(-n)リモートにファイルが存在しない場合にローカルからリモートにファイルをコピーするため。

Options are:
-r : recursive
-n : copy file if it doesn't exist in remote folder

だから呼び出す:

./a.out -r D1 D2

D1からまでのすべてのファイルとディレクトリを再帰的に同期しますD2D1に存在するファイルと存在しないファイルD2は無視されます。

そして呼び出し:

./a.cout -rn D1 D2

同じことを行いますが、に存在するファイルとに存在しD1ないファイルD2はにコピーされD2ます。

問題は、呼び出しは呼び出しと./a.out -rn同じではなく、ではないために機能しないことです。./a.out -nr./a.out -r -n(-n)D1

これが私がメインを実装する方法です。

int main(int argc, char** argv) {
  int next_option = 0;
  const char* const short_options = "hrn:";

  const struct option long_options[] = {
    { "help",      0, NULL,  'h' },
    { "recursive", 1, NULL,  'r' },
    { "new", 1, NULL,  'n' },
    { NULL,        0, NULL,  0   }
  };

  int recursive = 0;
  int new = 0;

  do {
    next_option = getopt_long(argc, argv, short_options, long_options, NULL);

    switch(next_option) {
      case 'r':
        recursive = 1;
        break;

      case 'n':
        new = 1;
        break;

      case 'h':
        print_help();
        return 0;

      case -1:
        break;

      default:
        print_help();
        return -1;
    }

  } while(next_option != -1);

  sync(argv[2], argv[3], recursive, new);

  return EXIT_SUCCESS;
}
4

2 に答える 2

3

ここには2つの(潜在的な)問題があります:

  1. :短いオプション文字列に迷いがあります。これにより-n、次のすべてを飲み込むオプションが使用されますr。また、必須の引数を取るように設定された長いオプションがあります。

  2. 引数番号を柔軟性のない方法でハードコーディングしており、それらが存在することをテストしていません。

これを試して:

int main(int argc, char** argv) {
  int next_option = 0;
  const char* const short_options = "hrn";
  extern int optind;

  const struct option long_options[] = {
    { "help",      no_argument, NULL,  'h' },
    { "recursive", no_argument, NULL,  'r' },
    { "new",       no_argument, NULL,  'n' },
    { NULL,        no_argument, NULL,  0   }
  };

  int recursive = 0;
  int new = 0;

  do {
    next_option = getopt_long(argc, argv, short_options, long_options, NULL);

    switch(next_option) {
      case 'r':
        recursive = 1;
        break;

      case 'n':
        new = 1;
        break;

      case 'h':
        print_help();
        return 0;

      case -1:
        break;

      default:
        print_help();
        return -1;
    }

  } while(next_option != -1);

  if (optind + 1 >= argc)
    return -1;

  sync(argv[optind], argv[optind+1], recursive, new);

  return EXIT_SUCCESS;
}
于 2012-12-11T11:41:44.307 に答える
1

のようなコマンドラインを使用する場合の問題は-r -n、への呼び出しでインデックスをハードコーディングしているためですsync。あなたはそれをすべきではありません。

マニュアルページを読むとgetopt_long(関数に問題がある場合は常に読んでください!)、次の行に気付くでしょう。

オプション文字がこれ以上ない場合、getopt()は-1を返します。その場合、 optindは、オプションではない最初のargv要素のargv内のインデックスです。

2番目の文を注意深く読んでください。

于 2012-12-11T11:37:39.313 に答える