19

私の議論はこんな感じです

./a.out -i file1 file2 file3

getopt()3つ(またはそれ以上)の入力ファイルを取得するにはどうすればよいですか?私はこのようなことをしています:

while ((opt = getopt(argc, argv, "i:xyz.."))!= -1){
  case 'i':
     input = optarg; 
     break;
  ...
}

私はちょうどfile1;を取得します。取得方法file2file3

4

5 に答える 5

31

私はこれがかなり古いことを知っていますが、解決策を探しているときにこれに出くわしました。

while((command = getopt(argc, argv, "a:")) != -1){

    switch(command){
        case 'a':

        (...)

        optind--;
        for( ;optind < argc && *argv[optind] != '-'; optind++){
              DoSomething( argv[optind] );         
        }

        break;
    }

int optind ( getopt()で使用されるextern )は、 getopt()で選択された「現在のargv 」の後の次の位置を指していることがわかりました。だから最初は減らします。

まず、forループは、現在の引数の値がargvの境界内にあるかどうかをチェックします(argcは配列の長さであるため、配列argvの最後の位置はargc-1です)。&&の2番目の部分は、次の引数の最初の文字が「-」であるかどうかを比較します。最初の文字が「-」の場合、現在の引数の次の値が不足します。それ以外の場合、argv[optind]が次の値になります。そして、argvが終了するか、引数の値がなくなるまで続きます。

最後に、次のargvをチェックするためにoptindをインクリメントします。

' optind <argc 'をチェックしているため、最初の部分がtrueでない限り、条件の最初の2番目の部分は実行されないため、配列の境界の外側を読み取る心配はありません。

PS私はまったく新しいCプログラマーです。誰かが改善点や批評を持っている場合は、それを共有してください。

于 2011-11-02T14:55:38.110 に答える
10

必要に応じて、自分で開始しargv[optind]て増分することができoptindます。ただし、その構文は貧弱な形式であると考えるので、これには反対することをお勧めします。(リストの最後に到達したことをどのようにして知ることができますか?誰かが-最初の文字としてaという名前のファイルを持っている場合はどうなりますか?)

構文を次のいずれかに変更する方がよいと思います。

/a.out -i file1 -i file2 -i file3

または、ファイルのリストを位置パラメータとして扱うには、次のようにします。

/a.out file1 file2 file3
于 2010-10-15T03:11:07.317 に答える
6

glibcの不適合な引数順列拡張は-i、この方法で複数の引数を使用しようとする試みを中断することに注意してください。また、非GNUシステムでは、「への2番目の引数-i」は、最初の非オプション引数として解釈され、それ以上のオプション解析を停止します。これらの問題を念頭に置いて、getoptこの構文を使用する場合は、独自のコマンドラインパーサーを削除して記述します。これは、でサポートされている構文ではないためgetoptです。

于 2010-10-15T04:09:16.053 に答える
6

上記のコードを調べて試しましたが、解決策が少し簡単で、うまく機能していることがわかりました。

私が欲しかった取り扱いは:

-m mux_i2c_group mux_i2c_out

(2つの引数が必要です)。

これが私のためにどのようにパンアウトしたかです:

case 'm':
    mux_i2c_group = strtol(optarg, &ch_p, 0);

    if (optind < argc && *argv[optind] != '-'){
        mux_i2c_out = strtol(argv[optind], NULL, 0);
        optind++;
    } else {
        fprintf(stderr, "\n-m option require TWO arguments <mux_group> "
                        "<mux_out>\n\n");
        usage();
    }

    use_mux_flag = 1;
    break;

これにより、通常どおり最初の値が取得され、2番目のREQUIRED値が検索されました。

于 2012-08-11T15:32:13.317 に答える
0

GoTTimwによるソリューションは、私にとって非常に有用であることが証明されています。ただし、ここではまだ提案されていないもう1つのアイデアについて説明します。

この方法で引数を1つの文字列として渡します。

./a.out -i "file1 file2 file3"

次に、1つの文字列を1つの引数として取得し、それをスペースで分割するだけで済みます。

于 2019-12-26T17:27:22.857 に答える