Linux選項解釋-getopt和getopt_long函式

gaig803發表於2009-06-16

Linux選項解釋-getopt和getopt_long函式

一、命令列簡介

解釋分析命令列通常是所以程式的第一個任務,C語言通過argc和argv引數來訪問它的命令列引數。

最簡單的命令列處理技術可以通過if判斷來表示,如下例:

if(argc>1 &&argv[1][0] ==  -  &&argv[1][1] ==  h )  //判斷命令列引數是否為-n

{

     do _ some thing();

}

這樣處理簡單有序的命令列還可以,對於複雜的命令列處理顯得有心無力,於是GNU提供兩個函式專門用來處理命令列引數:getopt和getopt_long。

二、getopt函式

getopt()函式宣告如下:

#include <unistd.h>

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

extern char *optarg;

extern int optind, opterr, optopt;
 

 

說 明:函式中的argc和argv通常直接從main()到兩個引數傳遞而來。optsting是選項引數組成的字串,如果該字串裡任一字母后有冒號, 那麼這個選項就要求有引數,optarg就是選項引數。optind是當前索引,optopt用於當發現無效選項字元的時候,getopt函式或者返回 “?”或者返回“:”字元,並且optopt包含了所發現的無效選項字元。

如果optstring引數的第一個字元是冒號,那麼getopt會根據錯誤情況返回不同的字元,當錯誤是無效選項,getopt返回“?”,當錯誤是缺少選項引數,getopt返回“:”。

注:GNU getopt()第三個特點是optstring中的選項字元後面接兩個冒號,就允許該選項有可選的選項引數。在選項引數不存在的情況下,GNU getopt()返回選項字元並將optarg設定為NULL。

例子:

#include <stdio.h>

#include <unistd.h>

#include <getopt.h>

char *para = ":ab:c";

int main(int argc, char *argv[])

{

     int oc = -1;

     char *b_input = NULL;

     while((oc = getopt(argc, argv, para)) != -1)

     {

         switch(oc)

         {

          case 'a':

              printf("input para is a\n");

              break;

          case 'b':

              b_input = optarg;

              printf("input para is b,and optarg is %s\n", b_input);

              break;

          case 'c':

              printf("input para is c\n");

              break;

          case ':':

              printf("option %c requires an argument\n",optopt);

              break;

          case '?':

          default:

              printf("option %c is invalid:ignored\n",optopt);

             break;

         }

     }

     return 0;

}
 

 

編譯:

[root@heguangwu projects]# gcc -o getopt_ex getopt_ex.c

執行:

[root@heguangwu projects]# ./getopt_ex -a

input para is a

[root@heguangwu projects]# ./getopt_ex -a -b

input para is a

option b requires an argument

[root@heguangwu projects]# ./getopt_ex -d

option d is invalid:ignored

 

三、getopt_long函式

getopt_long用來處理長選項,使用 man 3 getopt_long ,得到其宣告如下:

#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);
 

 

前三個引數與getopt相同,下一個引數是指向陣列的指標,這個陣列是option結構陣列,option結構稱為長選項表,其宣告如下:

struct option
 {

    const char *name;

    int  has_arg;

    int  *flag;

    int  val;

};
 

 

結構中的元素解釋如下:

const char *name :選項名,前面沒有短橫線

int has_arg:描述長選項是否有引數,其值見下表

符號常量

數值

含義

no_argument

required_argument

optional_argument

0

1

2

選項沒有引數

選項需要引數

選項引數是可選的

int *flag

如果該指標為NULL,那麼getopt_long返回val欄位的值;

如果該指標不為NULL,那麼會使得它所指向的結構填入val欄位的值,同時getopt_long返回0

int val

如果flag是NULL,那麼val通常是個字元常量,如果短選項和長選項一致,那麼該字元就應該與optstring中出現的這個選項的引數相同;

 

 

#include <stdio.h>

#include <unistd.h>

#include <getopt.h>

char *para = ":ab:cf:v";

int do_all = 0;

int do_help = 0; 

int do_version = 0;

char *file = NULL;

struct option longopt[] = 

{

     {"all", no_argument, &do_all, 1},

     {"file", required_argument, NULL, 'f'},

     {"help", no_argument, &do_help, 1},

     {"version", no_argument, &do_version, 1},

     {"bob", required_argument, NULL, 'b'},

     {0, 0, 0, 0},

};

int main(int argc, char *argv[])

{

    int oc = -1;

    char *b_input = NULL;

    while((oc = getopt_long(argc, argv, para, longopt, NULL)) != -1)

    {

         switch(oc)

         {

         case 'a':

               printf("input para is a\n");

              break;

         case 'b':

              b_input = optarg;

              printf("input para is b,and optarg is %s\n", b_input);

             break;

        case 'c':

             printf("input para is c\n");

            break;

        case 'v':

            printf("input para is v\n");

            break;

        case 'f':

            printf("input para is f\n");

            file = "hello world";

            break;

        case 0:

           break;

        case ':':

             printf("option %c requires an argument\n",optopt);

             break;

         case '?':

         default:

            printf("option %c is invalid:ignored\n",optopt);

            break;

         }

     }

     printf("do_all is %d\n",do_all);

     printf("do_help is %d\n",do_help);

     printf("do_version is %d\n",do_version);

     printf("do_file is %s\n",file);

     printf("bob is %s\n", b_input);

     return 0;

}
 

 

 

執行的結果: 只顯示關鍵結果

[root@heguangwu projects]# ./opt_ex2 -a

input para is a

 

[root@heguangwu projects]# ./opt_ex2 --all

do_all is 1

 

[root@heguangwu projects]# ./opt_ex2 -f h

input para is f

do_file is hello world

 

[root@heguangwu projects]# ./opt_ex2 --bob aa

input para is b,and optarg is aa

bob is aa

 

[root@heguangwu projects]# ./opt_ex2 -b aa

       input para is b,and optarg is aa

 

相關文章