日本a√视频在线,久久青青亚洲国产,亚洲一区欧美二区,免费g片在线观看网站

        <style id="k3y6c"><u id="k3y6c"></u></style>
        <s id="k3y6c"></s>
        <mark id="k3y6c"></mark>
          
          

          <mark id="k3y6c"></mark>

          "); //-->

          博客專欄

          EEPW首頁(yè) > 博客 > 命令行選項(xiàng)解析函數(shù)(C語(yǔ)言):getopt()和getopt_long()

          命令行選項(xiàng)解析函數(shù)(C語(yǔ)言):getopt()和getopt_long()

          發(fā)布人:電子禪石 時(shí)間:2019-12-12 來(lái)源:工程師 發(fā)布文章


          上午在看源碼項(xiàng)目 webbench 時(shí),剛開始就被一個(gè)似乎挺陌生函數(shù) getopt_long() 給卡住了,說(shuō)實(shí)話這函數(shù)沒(méi)怎么見過(guò),自然不知道這哥們是干什么的。于是乎百度了一番,原來(lái)是處理命令行選項(xiàng)參數(shù)的,的確,正規(guī)點(diǎn)的大型程序一般第一步就是處理命令行參數(shù)的,接著才是主干程序。在百度和 man 的幫助下,找到了具體使用方法和解釋,二話不說(shuō)趕緊學(xué)習(xí)一下,并總結(jié)出文檔記錄一下。

              平時(shí)在寫程序時(shí)常常需要對(duì)命令行參數(shù)進(jìn)行處理,因?yàn)閰?shù)少,自己解析就可以搞定;如果命令行個(gè)數(shù)比較多時(shí),如果按照順序一個(gè)一個(gè)定義參數(shù)含義很容易造成混亂,而且如果程序只按順序處理參數(shù)的話,一些“可選參數(shù)”的功能將很難實(shí)現(xiàn),這個(gè)問(wèn)題在 linux 中用 getopt 等函數(shù)可以優(yōu)雅地解決。

          一、查詢linux命令手冊(cè):

          復(fù)制代碼
          復(fù)制代碼
          #include<unistd.h>
          #include<getopt.h>          /*所在頭文件 */
          int getopt(intargc, char * const argv[], const char *optstring);
          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);
          extern char *optarg;         /*系統(tǒng)聲明的全局變量 */
          extern int optind, opterr, optopt;
          復(fù)制代碼
          復(fù)制代碼

          先拿最簡(jiǎn)單的 getopt 函數(shù)開刀,getopt_long 只是前者的增強(qiáng)版,功能多點(diǎn)而已。

          二、getopt函數(shù)

          1、定義

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

          2、描述

          getopt是用來(lái)解析命令行選項(xiàng)參數(shù)的,但是只能解析短選項(xiàng): -d 100,不能解析長(zhǎng)選項(xiàng):--prefix

          3、參數(shù)

          argc:main()函數(shù)傳遞過(guò)來(lái)的參數(shù)的個(gè)數(shù)
          argv:main()函數(shù)傳遞過(guò)來(lái)的參數(shù)的字符串指針數(shù)組
          optstring:選項(xiàng)字符串,告知 getopt()可以處理哪個(gè)選項(xiàng)以及哪個(gè)選項(xiàng)需要參數(shù)

          4、返回

          如果選項(xiàng)成功找到,返回選項(xiàng)字母;如果所有命令行選項(xiàng)都解析完畢,返回 -1;如果遇到選項(xiàng)字符不在 optstring 中,返回字符 '?';如果遇到丟失參數(shù),那么返回值依賴于 optstring 中第一個(gè)字符,如果第一個(gè)字符是 ':' 則返回':',否則返回'?'并提示出錯(cuò)誤信息。

          5、下邊重點(diǎn)舉例說(shuō)明optstring的格式意義:

          char*optstring = “ab:c::”;
          單個(gè)字符a         表示選項(xiàng)a沒(méi)有參數(shù)            格式:-a即可,不加參數(shù)
          單字符加冒號(hào)b:     表示選項(xiàng)b有且必須加參數(shù)      格式:-b 100或-b100,但-b=100錯(cuò)
          單字符加2冒號(hào)c::   表示選項(xiàng)c可以有,也可以無(wú)     格式:-c200,其它格式錯(cuò)誤

          上面這個(gè) optstring 在傳入之后,getopt 函數(shù)將依次檢查命令行是否指定了 -a, -b, -c(這需要多次調(diào)用 getopt 函數(shù),直到其返回-1),當(dāng)檢查到上面某一個(gè)參數(shù)被指定時(shí),函數(shù)會(huì)返回被指定的參數(shù)名稱(即該字母)

          optarg —— 指向當(dāng)前選項(xiàng)參數(shù)(如果有)的指針。
          optind —— 再次調(diào)用 getopt() 時(shí)的下一個(gè) argv指針的索引。
          optopt —— 最后一個(gè)未知選項(xiàng)。
          opterr -—— 如果不希望getopt()打印出錯(cuò)信息,則只要將全域變量opterr設(shè)為0即可。

          以上描述的并不生動(dòng),下邊結(jié)合實(shí)例來(lái)理解:

          6、實(shí)例:

          復(fù)制代碼
          復(fù)制代碼
          #include<stdio.h>
          #include<unistd.h>
          #include<getopt.h>
          int main(intargc, char *argv[])
          {
              int opt;
              char *string = "a::b:c:d";
              while ((opt = getopt(argc, argv, string))!= -1)
              {  
                  printf("opt = %c\t\t", opt);
                  printf("optarg = %s\t\t",optarg);
                  printf("optind = %d\t\t",optind);
                  printf("argv[optind] = %s\n",argv[optind]);
              }  
          }
          復(fù)制代碼
          復(fù)制代碼

          編譯上述程序并執(zhí)行結(jié)果:

          輸入選項(xiàng)及參數(shù)正確的情況

          dzlab:~/test/test#./opt -a100 -b 200 -c 300 -d
          opt = a         optarg = 100            optind = 2              argv[optind] = -b
          opt = b         optarg = 200            optind = 4              argv[optind] = -c
          opt = c         optarg = 300            optind = 6              argv[optind] = -d
          opt = d         optarg = (null)         optind = 7              argv[optind] = (null)

          或者這樣的選項(xiàng)格式(注意區(qū)別):

          dzlab:~/test/test#./opt -a100 -b200 -c300 -d 
          opt = a         optarg = 100            optind = 2              argv[optind] = -b200
          opt = b         optarg = 200            optind = 3              argv[optind] = -c300
          opt = c         optarg = 300            optind = 4              argv[optind] = -d
          opt = d         optarg = (null)         optind = 5              argv[optind] = (null)

          選項(xiàng)a是可選參數(shù),這里不帶參數(shù)也是正確的

          dzlab:~/test/test#./opt -a -b 200 -c 300 -d   
          opt = a         optarg = (null)         optind = 2              argv[optind] = -b
          opt = b         optarg = 200            optind = 4              argv[optind] = -c
          opt = c         optarg = 300            optind = 6              argv[optind] = -d
          opt = d         optarg = (null)         optind = 7              argv[optind] = (null)

          輸入選項(xiàng)參數(shù)錯(cuò)誤的情況

          dzlab:~/test/test#./opt -a 100 -b 200 -c 300 -d
          opt = a         optarg = (null)         optind = 2              argv[optind] = 100
          opt = b         optarg = 200            optind = 5              argv[optind] = -c
          opt = c         optarg = 300            optind = 7              argv[optind] = -d
          opt = d         optarg = (null)         optind = 8              argv[optind] = (null)

          導(dǎo)致解析錯(cuò)誤,第一個(gè) optarg = null,實(shí)際輸入?yún)?shù) 100,由于格式不正確造成的(可選參數(shù)格式固定)

          參數(shù)丟失,也會(huì)導(dǎo)致錯(cuò)誤,c選項(xiàng)是必須有參數(shù)的,不加參數(shù)提示錯(cuò)誤如下:

          dzlab:~/test/test#./opt -a -b 200 -c      
          opt = a         optarg = (null)         optind = 2              argv[optind] = -b
          opt = b         optarg = 200            optind = 4              argv[optind] = -c
          ./opt: optionrequires an argument -- 'c'
          opt = ?         optarg = (null)         optind = 5              argv[optind] = (null)

          這種情況,optstring 中第一個(gè)字母不是':',如果在 optstring 中第一個(gè)字母加':',則最后丟失參數(shù)的那個(gè)選項(xiàng) opt 返回的是':',不是'?',并且沒(méi)有提示錯(cuò)誤信息,這里不再列出。

          命令行選項(xiàng)未定義,-e選項(xiàng)未在optstring中定義,會(huì)報(bào)錯(cuò):

          dzlab:~/test/test#./opt -a -b 200 -e
          opt = a         optarg = (null)         optind = 2              argv[optind] = -b
          opt = b         optarg = 200             optind = 4              argv[optind] = -e
          ./opt: invalidoption -- 'e'
          opt = ?         optarg = (null)         optind = 5              argv[optind] = (null)

          到這里應(yīng)該已經(jīng)把getopt函數(shù)的功能講解清楚了吧,下邊來(lái)說(shuō)說(shuō) getopt_long 函數(shù),getopt_long 函數(shù)包含了 getopt 函數(shù)的功能,并且還可以指定"長(zhǎng)參數(shù)"(或者說(shuō)長(zhǎng)選項(xiàng)),與 getopt 函數(shù)對(duì)比,getopt_long 比其多了兩個(gè)參數(shù):

          三、getopt_long函數(shù)

          1、定義

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

          2、描述

          包含 getopt 功能,增加了解析長(zhǎng)選項(xiàng)的功能如:--prefix --help

          3、參數(shù)

          longopts    指明了長(zhǎng)參數(shù)的名稱和屬性
          longindex   如果longindex非空,它指向的變量將記錄當(dāng)前找到參數(shù)符合longopts里的第幾個(gè)元素的描述,即是longopts的下標(biāo)值

          4、返回

          對(duì)于短選項(xiàng),返回值同getopt函數(shù);對(duì)于長(zhǎng)選項(xiàng),如果flag是NULL,返回val,否則返回0;對(duì)于錯(cuò)誤情況返回值同getopt函數(shù)

          5、struct option

          struct option {
          const char  *name;       /* 參數(shù)名稱 */
          int          has_arg;    /* 指明是否帶有參數(shù) */
          int          *flag;      /* flag=NULL時(shí),返回value;不為空時(shí),*flag=val,返回0 */
          int          val;        /* 用于指定函數(shù)找到選項(xiàng)的返回值或flag非空時(shí)指定*flag的值 */
          };

          6、參數(shù)說(shuō)明:

          has_arg  指明是否帶參數(shù)值,其數(shù)值可選:
          no_argument         表明長(zhǎng)選項(xiàng)不帶參數(shù),如:--name, --help
          required_argument  表明長(zhǎng)選項(xiàng)必須帶參數(shù),如:--prefix /root或 --prefix=/root
          optional_argument  表明長(zhǎng)選項(xiàng)的參數(shù)是可選的,如:--help或 –prefix=/root,其它都是錯(cuò)誤

          接著看一下實(shí)例操作會(huì)更加深刻地理解:

          7、實(shí)例:

          復(fù)制代碼
          復(fù)制代碼
          int main(intargc, char *argv[])
          {
              int opt;
              int digit_optind = 0;
              int option_index = 0;
              char *string = "a::b:c:d";
              static struct option long_options[] =
              {  
                  {"reqarg", required_argument,NULL, 'r'},
                  {"optarg", optional_argument,NULL, 'o'},
                  {"noarg",  no_argument,         NULL,'n'},
                  {NULL,     0,                      NULL, 0},
              }; 
              while((opt =getopt_long_only(argc,argv,string,long_options,&option_index))!= -1)
              {  
                  printf("opt = %c\t\t", opt);
                  printf("optarg = %s\t\t",optarg);
                  printf("optind = %d\t\t",optind);
                  printf("argv[optind] =%s\t\t", argv[optind]);
                  printf("option_index = %d\n",option_index);
              }  
          }
          復(fù)制代碼
          復(fù)制代碼

          編譯上述程序并執(zhí)行結(jié)果:

          正確輸入長(zhǎng)選項(xiàng)的情況


          dzlab:~/test/test#./long --reqarg 100 --optarg=200 --noarg
          opt = r optarg =100     optind = 3   argv[optind] = --optarg=200  option_index = 0
          opt = o optarg =200     optind = 4   argv[optind] = --noarg        option_index = 1
          opt = n optarg =(null) optind = 5    argv[optind] =(null)          option_index = 2

          或者這種方式:

          dzlab:~/test/test#./long –reqarg=100 --optarg=200 --noarg
          opt = r optarg =100     optind = 2   argv[optind] = --optarg=200  option_index = 0
          opt = o optarg =200     optind = 3   argv[optind] = --noarg        option_index = 1
          opt = n optarg =(null) optind = 4    argv[optind] =(null)          option_index = 2

          可選選項(xiàng)可以不給參數(shù)

          dzlab:~/test/test#./long --reqarg 100 --optarg --noarg   
          opt = r optarg =100     optind = 3     argv[optind] = --optarg option_index = 0
          opt = o optarg =(null) optind = 4      argv[optind] =--noarg   option_index = 1
          opt = n optarg =(null) optind = 5      argv[optind] =(null)     option_index = 2

          輸入長(zhǎng)選項(xiàng)錯(cuò)誤的情況

          dzlab:~/test/test#./long --reqarg 100 --optarg 200 --noarg 
          opt = r optarg =100     optind = 3     argv[optind] = --optarg  option_index= 0
          opt = o optarg =(null) optind = 4      argv[optind] =200        option_index = 1
          opt = n optarg =(null) optind = 6      argv[optind] =(null)     option_index = 2

          這時(shí),雖然沒(méi)有報(bào)錯(cuò),但是第二項(xiàng)中 optarg 參數(shù)沒(méi)有正確解析出來(lái)(格式應(yīng)該是 —optarg=200)

          必須指定參數(shù)的選項(xiàng),如果不給參數(shù),同樣解析錯(cuò)誤如下:

          dzlab:~/test/test#./long --reqarg --optarg=200 --noarg    
          opt = r optarg =--optarg=200  optind = 3 argv[optind] =--noarg  option_index = 0
          opt = n optarg =(null)         optind = 4 argv[optind] =(null)    option_index = 2

          長(zhǎng)選項(xiàng)的舉例說(shuō)明暫且就這么多吧,其它如選項(xiàng)錯(cuò)誤、缺參數(shù)、格式不正確的情況自己再試驗(yàn)一下。

          四、getopt_long_only函數(shù)

          getopt_long_only 函數(shù)與 getopt_long 函數(shù)使用相同的參數(shù)表,在功能上基本一致,只是 getopt_long 只將 --name 當(dāng)作長(zhǎng)參數(shù),但 getopt_long_only 會(huì)將 --name 和 -name 兩種選項(xiàng)都當(dāng)作長(zhǎng)參數(shù)來(lái)匹配。getopt_long_only 如果選項(xiàng) -name 不能在 longopts 中匹配,但能匹配一個(gè)短選項(xiàng),它就會(huì)解析為短選項(xiàng)。


          *博客內(nèi)容為網(wǎng)友個(gè)人發(fā)布,僅代表博主個(gè)人觀點(diǎn),如有侵權(quán)請(qǐng)聯(lián)系工作人員刪除。

          晶體管相關(guān)文章:晶體管工作原理


          晶體管相關(guān)文章:晶體管原理


          關(guān)鍵詞:

          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉