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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > c/c++ >内容正文

c/c++

C/C++ getopt()函数的介绍及使用

發(fā)布時(shí)間:2025/3/15 c/c++ 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C/C++ getopt()函数的介绍及使用 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

函數(shù)原型:

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

前兩個(gè)參數(shù)大家不會(huì)陌生,沒(méi)錯(cuò),就是老大main函數(shù)的兩個(gè)參數(shù)!老大傳進(jìn)來(lái)的參數(shù)自然要有人接著!

第三個(gè)參數(shù)是個(gè)字符串,看名字,我們可以叫他選項(xiàng)字符串(后面會(huì)說(shuō)明)

返回值為int類(lèi)型,我們都知道char類(lèi)型是可以轉(zhuǎn)換成int類(lèi)型的,每個(gè)字符都有他所對(duì)應(yīng)的整型值,其實(shí)這個(gè)返回值返回的就是一個(gè)字符,什么字符呢,叫選項(xiàng)字符(姑且這么叫吧,后面會(huì)進(jìn)一步說(shuō)明)

在此之前還要介紹他的幾個(gè)兄弟

小弟1:extern char* optarg;

小弟2:extern int optind;

小弟3:extern int opterr;

小弟4:extern int optopt;

  • 小弟1是用來(lái)保存選項(xiàng)的參數(shù)的(先混個(gè)臉熟,后面有例子);
  • 小弟2用來(lái)記錄下一個(gè)檢索位置;
  • 小弟3表示的是是否將錯(cuò)誤信息輸出到stderr,為0時(shí)表示不輸出,
  • 小弟4表示不在選項(xiàng)字符串optstring中的選項(xiàng)(有點(diǎn)亂哈,后面會(huì)有例子)

問(wèn)題1:選項(xiàng)到底是個(gè)什么鬼?

? ? ? ? 在linux下大家都用過(guò)這樣一條指令吧:gcc helloworld.c -o helloworld.out;?這條指令中的-o就是命令行的選項(xiàng),而后面的helloworld.out就是-o選項(xiàng)所攜帶的參數(shù)。當(dāng)然熟悉shell指令的人都知道(雖然我并不熟悉),有些選項(xiàng)是不用帶參數(shù)的,而這樣不帶參數(shù)的選項(xiàng)可以寫(xiě)在一起(這一點(diǎn)在后面的例子中會(huì)用到,希望理解),比如說(shuō)有兩個(gè)選項(xiàng)-c和-d,這兩個(gè)選項(xiàng)都不帶參數(shù)(而且明顯是好基友),那么他們是可以寫(xiě)在一起,寫(xiě)成-cd的。實(shí)際的例子:當(dāng)我們刪除一個(gè)文件夾時(shí)可以使用指令?rm 目錄名 -rf,本來(lái)-r表示遞歸刪除,就是刪除文件夾中所有的東西,-f表示不提示就立刻刪除,他們兩個(gè)都不帶參數(shù),這時(shí)他們就可以寫(xiě)在一起。

問(wèn)題2:選項(xiàng)字符串又是何方神圣?

? ? ? ? "a:b:cd::e",這就是一個(gè)選項(xiàng)字符串。對(duì)應(yīng)到命令行就是-a ,-b ,-c ,-d, -e 。冒號(hào)又是什么呢??冒號(hào)表示參數(shù),一個(gè)冒號(hào)就表示這個(gè)選項(xiàng)后面必須帶有參數(shù)(沒(méi)有帶參數(shù)會(huì)報(bào)錯(cuò)哦),但是這個(gè)參數(shù)可以和選項(xiàng)連在一起寫(xiě),也可以用空格隔開(kāi),比如-a123 和-a ? 123(中間有空格) 都表示123是-a的參數(shù);兩個(gè)冒號(hào)的就表示這個(gè)選項(xiàng)的參數(shù)是可選的,即可以有參數(shù),也可以沒(méi)有參數(shù),但要注意有參數(shù)時(shí),參數(shù)與選項(xiàng)之間不能有空格(有空格會(huì)報(bào)錯(cuò)的哦),這一點(diǎn)和一個(gè)冒號(hào)時(shí)是有區(qū)別的。

好了,先給個(gè)代碼,然后再解釋吧。

#include <unistd.h> #include <stdio.h> int main(int argc, char * argv[]) {int ch;printf("\n\n");printf("optind:%d,opterr:%d\n",optind,opterr);printf("--------------------------\n");while ((ch = getopt(argc, argv, "ab:c:de::")) != -1){printf("optind: %d\n", optind);switch (ch) {case 'a':printf("HAVE option: -a\n\n"); break;case 'b':printf("HAVE option: -b\n"); printf("The argument of -b is %s\n\n", optarg);break;case 'c':printf("HAVE option: -c\n");printf("The argument of -c is %s\n\n", optarg);break;case 'd':printf("HAVE option: -d\n");break;case 'e':printf("HAVE option: -e\n");printf("The argument of -e is %s\n\n", optarg);break;case '?':printf("Unknown option: %c\n",(char)optopt);break;}}}

編譯后命令行執(zhí)行:# ./main -b "qing er"

輸出結(jié)果為:

optind:1,opterr:1
--------------------------
optind: 3
HAVE option: -b
The argument of -b is qing er

?

? ? ? ? 我們可以看到:optind和opterr的初始值都為1,前面提到過(guò)opterr非零表示產(chǎn)生的錯(cuò)誤要輸出到stderr上。那么optind的初值為什么是1呢?

? ? ? ? 這就要涉及到main函數(shù)的那兩個(gè)參數(shù)了,argc表示參數(shù)的個(gè)數(shù),argv[]表示每個(gè)參數(shù)字符串,對(duì)于上面的輸出argc就為3,argv[]分別為: ./main 和 -b 和"qing er" ,實(shí)際上真正的參數(shù)是用第二個(gè)-b 開(kāi)始,也就是argv[1],所以optind的初始值為1;

? ? ? ? 當(dāng)執(zhí)行g(shù)etopt()函數(shù)時(shí),會(huì)依次掃描每一個(gè)命令行參數(shù)(從下標(biāo)1開(kāi)始),第一個(gè)-b,是一個(gè)選項(xiàng),而且這個(gè)選項(xiàng)在選項(xiàng)字符串optstring中有,我們看到b后面有冒號(hào),也就是b后面必須帶有參數(shù),而"qing er"就是他的參數(shù)。所以這個(gè)命令行是符合要求的。至于執(zhí)行后optind為什么是3,這是因?yàn)閛ptind是下一次進(jìn)行選項(xiàng)搜索的開(kāi)始索引,也是說(shuō)下一次getopt()函數(shù)要從argv[3]開(kāi)始搜索。當(dāng)然,這個(gè)例子argv[3]已經(jīng)沒(méi)有了,此時(shí)getopt()函數(shù)就會(huì)返回-1。

再看一個(gè)輸入:

?./main -b "qing er" -c1234

輸出結(jié)果為:

optind:1,opterr:1
--------------------------
optind: 3
HAVE option: -b
The argument of -b is qing er

optind: 4
HAVE option: -c
The argument of -c is 1234

? ? ? ? 對(duì)于這個(gè)過(guò)程會(huì)調(diào)用三次getopt()函數(shù),和第一個(gè)輸入一樣,是找到選項(xiàng)-b和他的參數(shù)"qing er",這時(shí)optind的值為3,也就意味著,下一次的getopt()要從argv[3]開(kāi)始搜索,所以第二次調(diào)用getopt()函數(shù),找到選項(xiàng)-c和他的參數(shù)1234(選項(xiàng)和參數(shù)是連在一起的),由于-c1234寫(xiě)在一起,所以他兩占一起占用argv[3],所以下次搜索從argv[4]開(kāi)始,而argv[4]為空,這樣第三次調(diào)用getopt()函數(shù)就會(huì)返回-1,循環(huán)隨之結(jié)束。

接下來(lái)我們看一個(gè)錯(cuò)誤的命令行輸入:?./main -z 123

輸出為:

optind:1,opterr:1
--------------------------
./main: invalid option -- 'z'
optind: 2
Unknown option: z

其中./main: invalid option -- 'z'就是輸出到stderr的錯(cuò)誤輸出。如果把opterr設(shè)置為0那么就不會(huì)有這條輸出。

在看一個(gè)錯(cuò)誤的命令行輸入:?./main -zheng

optind:1,opterr:1
--------------------------
./main: invalid option -- 'z'
optind: 1
Unknown option: z
./main: invalid option -- 'h'
optind: 1
Unknown option: h
optind: 2
HAVE option: -e
The argument of -e is ng

前面提到過(guò)不帶參數(shù)的選項(xiàng)可以寫(xiě)在一起,所以當(dāng)getopt()找到-z的時(shí)候,發(fā)現(xiàn)在optstring 中沒(méi)有,這時(shí)候他就認(rèn)為h也是一個(gè)選項(xiàng),也就是-h和-z寫(xiě)在一起了,依次類(lèi)推,直到找到-e,發(fā)現(xiàn)optstring中有。

? ? ? ?

? ? ? ? 最后要說(shuō)明一下,getopt()會(huì)改變argv[]中參數(shù)的順序。經(jīng)過(guò)多次getopt()后,argv[]中的選項(xiàng)和選項(xiàng)的參數(shù)會(huì)被放置在數(shù)組前面,而optind 會(huì)指向第一個(gè)非選項(xiàng)和參數(shù)的位置。看例子

#include <unistd.h> #include <stdio.h> int main(int argc, char * argv[]) {int i;printf("--------------------------\n");for(i=0;i<argc;i++){printf("%s\n",argv[i]);}printf("--------------------------\n");//int aflag=0, bflag=0, cflag=0;int ch;printf("\n\n");printf("optind:%d,opterr:%d\n",optind,opterr);printf("--------------------------\n");while ((ch = getopt(argc, argv, "ab:c:de::")) != -1){printf("optind: %d\n", optind);switch (ch) {case 'a':printf("HAVE option: -a\n\n"); break;case 'b':printf("HAVE option: -b\n"); printf("The argument of -b is %s\n\n", optarg);break;case 'c':printf("HAVE option: -c\n");printf("The argument of -c is %s\n\n", optarg);break;case 'd':printf("HAVE option: -d\n");break;case 'e':printf("HAVE option: -e\n");printf("The argument of -e is %s\n\n", optarg);break;case '?':printf("Unknown option: %c\n",(char)optopt);break;}}printf("----------------------------\n");printf("optind=%d,argv[%d]=%s\n",optind,optind,argv[optind]);printf("--------------------------\n");for(i=0;i<argc;i++){printf("%s\n",argv[i]);}printf("--------------------------\n");}

命令行:./main zheng -b "qing er" han -c123 qing

輸出結(jié)果為:

--------------------------
./main
zheng
-b
qing er
han
-c123
qing
--------------------------


optind:1,opterr:1
--------------------------
optind: 4
HAVE option: -b
The argument of -b is qing er

optind: 6
HAVE option: -c
The argument of -c is 123

----------------------------
optind=4,argv[4]=zheng
--------------------------
./main
-b
qing er
-c123
zheng
han
qing
--------------------------

可以看到最開(kāi)始argv[]內(nèi)容為:

./main
zheng
-b
qing er
han
-c123
qing

?

在執(zhí)行了多次getopt后變成了

./main
-b
qing er
-c123
zheng
han
qing

? ? ? ? 我們看到,被getopt挑出的選項(xiàng)和對(duì)應(yīng)的參數(shù)都按順序放在了數(shù)組的前面,而那些既不是選項(xiàng)又不是參數(shù)的會(huì)按順序放在后面。而此時(shí)optind為4,即指向第一個(gè)非選項(xiàng)也非選項(xiàng)的參數(shù),zheng

總結(jié)

以上是生活随笔為你收集整理的C/C++ getopt()函数的介绍及使用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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