日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

命令行选项解析函数(C语言):getopt()和getopt_long()

發(fā)布時(shí)間:2025/3/15 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 命令行选项解析函数(C语言):getopt()和getopt_long() 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

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

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

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

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

先拿最簡(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是用來解析命令行選項(xiàng)參數(shù)的,但是只能解析短選項(xiàng): -d 100,不能解析長選項(xiàng):--prefix

3、參數(shù)

argc:main()函數(shù)傳遞過來的參數(shù)的個(gè)數(shù) argv:main()函數(shù)傳遞過來的參數(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)舉例說明optstring的格式意義:

char*optstring = “ab:c::”; 單個(gè)字符a 表示選項(xiàng)a沒有參數(shù) 格式:-a即可,不加參數(shù) 單字符加冒號(hào)b: 表示選項(xiàng)b有且必須加參數(shù) 格式:-b 100或-b100,但-b=100錯(cuò) 單字符加2冒號(hào)c:: 表示選項(xiàng)c可以有,也可以無 格式:-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í)例來理解:

6、實(shí)例:

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

編譯上述程序并執(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 返回的是':',不是'?',并且沒有提示錯(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ù)的功能講解清楚了吧,下邊來說說 getopt_long 函數(shù),getopt_long 函數(shù)包含了 getopt 函數(shù)的功能,并且還可以指定"長參數(shù)"(或者說長選項(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 功能,增加了解析長選項(xiàng)的功能如:--prefix --help

3、參數(shù)

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

4、返回

對(duì)于短選項(xiàng),返回值同getopt函數(shù);對(duì)于長選項(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ù)說明:

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

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

7、實(shí)例:

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

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

正確輸入長選項(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

輸入長選項(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í),雖然沒有報(bào)錯(cuò),但是第二項(xiàng)中 optarg 參數(shù)沒有正確解析出來(格式應(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

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

四、getopt_long_only函數(shù)

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

轉(zhuǎn)載于:https://www.cnblogs.com/chenliyang/p/6633739.html

與50位技術(shù)專家面對(duì)面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖

總結(jié)

以上是生活随笔為你收集整理的命令行选项解析函数(C语言):getopt()和getopt_long()的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。