今天在看代碼時發現getopt函數的一段代碼,從網上找了相關的博客,學會了該函數的基本使用方法。總結記錄如下:
1、這個函數在linux命令行下:可以使用man 3 getopt 來查看對該函數的介紹: int getopt(int argc, char * const argv[],
const char *optstring);
該函數有三個參數:其中前兩個和void main(int argc, char * argv[])中的一樣,其實getopt的前兩個參數就是接收main函數傳遞過來的argc(命令行參數的個數)和argv(指向命令行的指針數組),第三個參數是命令字符串。根據man 3 getopt 後面對該函數的解釋“If an option was successfully found, then getopt() returns the option character. If all command-line options have been
parsed, then getopt() returns -1. If getopt() encounters an option character that was not in optstring, then '?' is
returned. If getopt() encounters an option with a missing argument, then the return value depends on the first character
in optstring: if it is ':', then ':' is returned; otherwise '?' is returned.”
所以這個函數解析成功之後返回的是選項字符,因爲是字符所以可以轉成int類型,所以函數返回值是int類型。
2、在man 3 getopt 對該函數的解釋那還有extern char *optarg; extern int optind, opterr, optopt;這幾個參數跟這個函數關係是十分密切的:optarg是用來保存選項的參數;optind用來保存下一次要索引的字符串的索引值;opterr表示是否將錯誤信息輸出到stderr,如果是0表示不輸出,否則輸出,默認是1;optopt表示輸入的選項不再optstring中的選項。
3、講到這有人可能還不明白什麼是命令選項:gcc test.c -o app 這個命令中,-o就叫命令選項,app就是這個選項的參數。這個命令行選項是可以一起的:比如 rm app -rf;當兩個命令後面都不帶參數時時可以寫在一起的。
4、這裏我們重點介紹getopt函數的第三個參數:optstring,看名字時選項字符串的意思。我們根據例子講解這個參數的使用“nb:o:t”,這個選項字符串如果是這樣,那麼在命令行輸入的時候就要-n、-b、-o、-t這樣輸入。其中一個“:”表示這個選項後面必須跟一個參數,這個參數可以直接和命令選項寫在一起,也可以用空格隔開;"::"兩個冒號表示該命令選項後面的參數可以帶也可以不帶,如果帶參數的話,命令和參數之間不能有空格。(!!!!!!!!!!!!!!)
用一個例子說明以上的講解:
int main(int argc,char *argv[])
{
int opt=-1;
while((opt=getopt(argc,argv,"nb:o::t"))!=-1)
{
printf("opt=%c,optarg=%s,optind=%d,argv[optind]=%s.optopt=%c\n",
opt,optarg,optind,argv[optind],optopt);
}
return 0;
}
生成的應用程序是app.
(1)./app -x -y -z 就會輸出錯誤信息如下:
./app: invalid option -- 'x'
opt=?,optarg=(null),optind=2,argv[optind]=-y.
./app: invalid option -- 'y'
opt=?,optarg=(null),optind=3,argv[optind]=-z.
./app: invalid option -- 'z'
opt=?,optarg=(null),optind=4,argv[optind]=(null).
(2) ./app -n -b 123 -o -t
opt=n,optarg=(null),optind=2,argv[optind]=-b.
opt=b,optarg=123,optind=4,argv[optind]=-o.
opt=o,optarg=(null),optind=5,argv[optind]=-t.
opt=t,optarg=(null),optind=6,argv[optind]=(null).
(3)如果-n後面帶參數的話,那麼會報錯:
./app -n12 -b 3 -o -t
opt=n,optarg=(null),optind=1,argv[optind]=-n12.
./app: invalid option -- '1'
opt=?,optarg=(null),optind=1,argv[optind]=-n12.
./app: invalid option -- '2'
opt=?,optarg=(null),optind=2,argv[optind]=-b.
opt=b,optarg=3,optind=4,argv[optind]=-o.
opt=o,optarg=(null),optind=5,argv[optind]=-t.
opt=t,optarg=(null),optind=6,argv[optind]=(null).
(4)如果雙冒號的選項後面帶參數用空格隔開的話:
./app -n -b 123 -o 456 -t
opt=n,optarg=(null),optind=2,argv[optind]=-b.
opt=b,optarg=123,optind=4,argv[optind]=-o.
opt=o,optarg=(null),optind=5,argv[optind]=456. ---------》紅色標記部分正確的話應該是456纔對,有空格不能識別。
opt=t,optarg=(null),optind=7,argv[optind]=(null).
(5)雙冒號的選項後面帶參數不用空格隔開(正確的方式):
./app -n -b 123 -o456 -t
opt=n,optarg=(null),optind=2,argv[optind]=-b.
opt=b,optarg=123,optind=4,argv[optind]=-o456.
opt=o,optarg=456,optind=5,argv[optind]=-t.
opt=t,optarg=(null),optind=6,argv[optind]=(null).