4
#include <iostream>
#include <getopt.h>

#define no_argument 0
#define required_argument 1 
#define optional_argument 2


int main(int argc, char * argv[])
{
  std::cout << "Hello" << std::endl;

  const struct option longopts[] =
  {
    {"version",   no_argument,        0, 'v'},
    {"help",      no_argument,        0, 'h'},
    {"stuff",     required_argument,  0, 's'},
    {0,0,0,0},
  };

  int index;
  int iarg=0;

  //turn off getopt error message
  opterr=1; 

  while(iarg != -1)
  {
    iarg = getopt_long(argc, argv, "s:vh", longopts, &index);

    switch (iarg)
    {
      case 'h':
        std::cout << "You hit help" << std::endl;
        break;

      case 'v':
        std::cout << "You hit version" << std::endl;
        break;

      case 's':
        std::cout << "You hit stuff" << std::endl;

        if(optarg)
          std::cout << "Your argument(s): " << optarg << std::endl;

        break;
    }
  }

  std::cout << "GoodBye!" << std::endl;

  return 0; 
}

必要な出力:

./a.out --stuff someArg1 someArg2

Hello
You hit stuff
Your agument(s): someArg1 someArg2
GoodBye!
4

4 に答える 4

7

すべてのオプション引数が処理されると、 getoptは-1を返します。この--stuff場合、は引数を取るオプションとして認識されますsomeArg1。argはまたはでsomeArg2始まらないため、オプションではありません。デフォルトでは、これはの末尾に並べ替えられます。getoptが-1を返した後、すべての非オプション引数はfromから:になります。---argvargvoptindargc-1

while (iarg != -1) {
    iarg = getopt_long(argc, argv, "s:vh", longopts, &index);
    // ...
}

for (int i = optind; i < argc; i++) {
    cout << "non-option arg: " << argv[i] << std::endl;
}

-の先頭にシングルを追加するとoptstringgetoptは1( '1'ではなく)を返しoptarg、オプション以外のパラメーターを指します。

while (iarg != -1) {
    iarg = getopt_long(argc, argv, "-s:vh", longopts, &index);

    switch (iarg)
    {
      // ...
      case 1:
        std::cout << "You hit a non-option arg:" << optarg << std::endl;
        break;
    }
}
于 2012-01-10T23:07:07.373 に答える
4

この行./a.out --stuff someArg1 someArg2で、シェルはa.outに対する3つの引数を解釈します。シェルで「someArg1someArg2」を1つの引数として解釈する必要があるため、単語を引用符で囲みます。

./a.out --stuff "someArg1 someArg2"
于 2012-01-10T19:56:54.113 に答える
0

私はWindowsに取り組んでいるので、この優れたソースからgetoptとgetopt_longをコンパイルする必要がありました

getopt_long.c(下記)を変更して、2つの入力引数に対応しました。私は、複数の引数のより一般的なケースを気にしませんでした。なぜなら、それは私が時間/必要としていたよりも多くの(そしてよりクリーンな)やり直しを必要とするからです。2番目の引数は、別のグローバル「optarg2」に配置されます。

ソースからgetoptをコンパイルする必要がない場合は、上記のフランクの答えがよりエレガントです。

extern char * optarg2
.
.
.
int getopt_long(nargc, nargv, options, long_options, index) 
{
.
.
.
if (long_options[match].has_arg == required_argument ||
            long_options[match].has_arg == optional_argument ||
            long_options[match].has_arg == two_req_arguments) {
            if (has_equal)
                optarg = has_equal;
            else
                optarg = nargv[optind++];
            if (long_options[match].has_arg == two_req_arguments) {
                optarg2 = nargv[optind++];
            }
        }
        if ((long_options[match].has_arg == required_argument ||
             long_options[match].has_arg == two_req_arguments)
            && (optarg == NULL)) {
            /*
             * Missing argument, leading :
             * indicates no error should be generated
             */
            if ((opterr) && (*options != ':'))
                (void)fprintf(stderr,
                  "%s: option requires an argument -- %s\n",
                  __progname(nargv[0]), current_argv);
            return (BADARG);
        }
        if ((long_options[match].has_arg == two_req_arguments)
            && (optarg2 == NULL)) {
            /*
             * Missing 2nd argument, leading :
             * indicates no error should be generated
             */
            if ((opterr) && (*options != ':'))
                (void)fprintf(stderr,
                  "%s: option requires 2nd argument -- %s\n",
                  __progname(nargv[0]), current_argv);
            return (BADARG);
        }

また、適切と思われる場合は、getopt.hに「two_required_args」または「multiple_args」の定義を追加する必要があります。

編集:私はマークダウンが苦手です

于 2016-05-24T12:49:50.857 に答える
0

optargは「someArg1」を指し、argv [optind]が存在し、オプションでない場合は「someArg2」です。単にそれを使用し、optindをインクリメントすることでそれを消費することができます。

case 's':
    std::cout << "You hit stuff" << std::endl;

    if (optind < argc && argv[optind][0] != '-') {
       std::cout << "Your argument(s): " << optarg << argv[optind] << std::endl;
       optind++;
    } else {
        printusage();
    }
    break;

これは任意の数の引数に対して機能することに注意してください。

case 's':
    std::cout << "You hit stuff." << std::endl;
    std::cout << "Your arguments:" std::endl << optarg << std::endl;

    while (optind < argc && argv[optind][0] != '-') {
       std::cout << argv[optind] << std::endl;
       optind++;
    } 
    break;

于 2018-06-05T18:31:29.120 に答える