web-dev-qa-db-ja.com

Cgetopt複数値

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

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

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

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

_file1_だけを取得します。 _file2_、_file3_を取得する方法は?

19
w00d

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

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

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

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

/a.out file1 file2 file3
9
jamesdlin

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

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

    switch(command){
        case 'a':

        (...)

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

        break;
    }

int optindgetopt()で使用されるextern)は、 'current /の後の次の位置を指していることがわかりました。argv'getopt();によって選択だから最初は減らします。

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

最後にoptindをインクリメントして、次の引数をチェックします。

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

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

28
GoTTimw

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

6
R..

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

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

-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値が検索されました。

5
Andrew Ward

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

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

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

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

0