getoptとgetopt_long関数の使用詳細


**getopt getopt_long      **
           ,main                 ,      linux                。
#include <unistd.h>

       int getopt(int argc, char * const argv[],
                  const char *optstring);

       extern char *optarg;
       extern int optind, opterr, optopt;

       #include <getopt.h>

       int getopt_long(int argc, char * const argv[],
                  const char *optstring,
                  const struct option *longopts, int *longindex);

       int getopt_long_only(int argc, char * const argv[],
                  const char *optstring,
                  const struct option *longopts, int *longindex);

optstringのフォーマットの例は、次のように便利です.
char *optstring = "abcd:";

上記のoptstringが入力されると、getopt関数はコマンドラインに-a,-b,-cおよび-dが指定されているかどうかを順次チェックします(これは、-1を返すまでgetopt関数を複数回呼び出す必要があります).上記のパラメータが指定されていることをチェックすると、関数は指定されたパラメータ名(すなわち、アルファベット)を返します.
最後のパラメータdの後ろには、パラメータdが-d 100や-d userなどの値を指定できることを示すコロンが付いています.
optindは、argvで処理される次のパラメータの下付き値を表す.
opterr=0を指定すると、getopt、getopt_long、getopt_long_onlyエラーが発生すると、エラー情報は標準出力ストリームに出力されません.
このうち4つの変数は、optarg:現在の位置のパラメータ、:後のパラメータによく使用されます.optind:optindは、argvで処理される次のパラメータの下付き値opterr:エラー情報optopt:を表す.
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
    int opt;
    char *optstring = "a:b:c:d";

    while ((opt = getopt(argc, argv, optstring)) != -1)
    {
        printf("opt = %c
"
, opt); printf("optarg = %s
"
, optarg); printf("optind = %d
"
, optind); printf("argv[optind - 1] = %s

"
, argv[optind - 1]); } return 0; }

出力結果:
ubuntu:~/Desktop/getopt$ ./test_getopt -a 100 -b 200 -c admin -d
opt = a
optarg = 100
optind = 3
argv[optind - 1] = 100

opt = b
optarg = 200
optind = 5
argv[optind - 1] = 200

opt = c
optarg = admin
optind = 7
argv[optind - 1] = admin

opt = d
optarg = (null)
optind = 8
argv[optind - 1] = -d

次はgetopt_long関数、getopt_long関数にはgetopt関数の機能が含まれており、getopt関数と比較してgetopt_longは2つのパラメータよりも多くなっています.
   int getopt(int argc, char * const argv[],
               const char *optstring);

   int getopt_long(int argc, char * const argv[],
               const char *optstring,
              const struct option *longopts, int *longindex);

ここでlongoptsは、option構造体からなる配列を指し、その配列の各要素は、「長いパラメータ」(すなわち、-nameのようなパラメータ)の名前と性質を示す.
       struct option {
            const char *name;
            int         has_arg;
            int        *flag;
            int         val;
        };

    name        

   has_arg         ,     :
          no_argument (  0)            (     , :--name)
          required_argument (  1)             (      , :--name Bob)
        optional_argument( 2)                 ,( --name --name Bob  )

   flag             ,     val    getopt_long        ,     ,val      flag       ,       0

    val                    ,   flag     flag       。

もう1つのパラメータlongindexは、longindexが空でない場合、現在見つかっているパラメータがlongoptsのいくつかの要素に合致する説明、すなわちlongoptsの下付き値を記録します.
static const struct option long_options[]=
{
 {"force",no_argument,&force,1},
 {"reload",no_argument,&force_reload,1},
 {"time",required_argument,NULL,'t'},
 {"help",no_argument,NULL,'?'},
 {"http09",no_argument,NULL,'9'},
 {"http10",no_argument,NULL,'1'},
 {"http11",no_argument,NULL,'2'},
 {"get",no_argument,&method,METHOD_GET},
 {"head",no_argument,&method,METHOD_HEAD},
 {"options",no_argument,&method,METHOD_OPTIONS},
 {"trace",no_argument,&method,METHOD_TRACE},
 {"version",no_argument,NULL,'V'},
 {"proxy",required_argument,NULL,'p'},
 {"clients",required_argument,NULL,'c'},
 {NULL,0,NULL,0}
};
while((opt=getopt_long(argc,argv,"912Vfrt:p:c:?h",long_options,&options_index))!=EOF )
 {
  switch(opt)
  {
   case  0 : break;
   case 'f': force=1;break;
   case 'r': force_reload=1;break; 
   case '9': http10=0;break;
   case '1': http10=1;break;
   case '2': http10=2;break;
   case 'V': printf(PROGRAM_VERSION"
"
);exit(0); case 't': benchtime=atoi(optarg);break; case 'p': /* proxy server parsing server:port */ tmp=strrchr(optarg,':'); proxyhost=optarg; if(tmp==NULL) { break; } if(tmp==optarg) { fprintf(stderr,"Error in option --proxy %s: Missing hostname.
"
,optarg); return 2; } if(tmp==optarg+strlen(optarg)-1) { fprintf(stderr,"Error in option --proxy %s Port number is missing.
"
,optarg); return 2; } *tmp='\0'; proxyport=atoi(tmp+1);break; case ':': case 'h': case '?': usage();return 2;break; case 'c': clients=atoi(optarg);break; }

そこからgetoptの使い方を学ぶことができますlong関数の使用.