Linux下 頭文件<getopt.h> 及其函數的應用
本文內容摘抄自:https://www.cnblogs.com/qingergege/p/5914218.html
函數一:
int getopt(int argc, char* argv[], const char* optstring);
參數1、2為 main函數的輸入參數,參數3 為選項字符串,函數返回值為選項字符。
<getopt.h 文件內部的參數:
1、 extern char* optarg ; 用於保存選項。
2、 extern int optind, 用來記錄下一個檢索位置。
3、 extern int opterr, 是否將錯誤的信息輸出到stderr,為0時表示不輸出。
4、 extern int optopt, 表示不在選項字符串optstring中的選項。
先來看一條指令: gcc helloworld.c -o helloworld.out; 這條指令中的-o就是命令行的選項,而後面的helloworld.out 就是選項-o選項所攜帶的參數。 有些選項是不帶參數的,而這樣不帶參數的選項可以寫在一起, 比如說有兩個選項 -c和-d,這兩個選項都不帶參數,那麽他們是可以寫在一起的,即:-cd 。
關於選項字符串: 比如 “a:b:cd::e”,這就是一個選項字符串。對應到命令行就是 -a, -b, -c, -d, -e 。 冒號表示參數,一個冒號就表示這個選項後面必須帶有參數。這個參數可以和選項連在一起,也可以用空格隔開,比如:-a123 和 -a 123 ,都表似乎123為-a的參數。兩個冒號就表示這個選項的參數是可選的,即可以有參數也可以沒有參數,但要註意有參數時參數與選項之間不能有空格。
一個例子:
/* ============================================================================ Name : test.c Author : lgh ============================================================================ */ #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) { switch(ch) { case ‘a‘: printf("a\n\n"); printf("the argument of -a is %s\n\n",optarg); break; case ‘b‘: printf("b\n\n"); printf("the argument of -b is %s\n\n",optarg); break; case ‘c‘: printf("c\n\n"); printf("the argument of -c is %s\n\n",optarg); break; case ‘d‘: printf("d\n\n"); break; case ‘e‘: printf("e\n\n"); printf("the argument of -e is %s\n\n",optarg); break; case ‘?‘: printf("unknown option: %c\n",(char)optopt); break; } printf("下一次起始搜索位置:optind = %d\n",optind); printf("-----------------------------------------------------------\n"); printf("\n\n"); } }
編譯後命令執行 ./test -b "hello world"
輸出結果為:
optind:1, opterr:1 ----------------------------------------------------------- b the argument of -b is hello world 下一次起始搜索位置:optind = 3 -----------------------------------------------------------
可以看到optind 和 opterr的初始值都為1 ,opterr非零表示如果發生錯誤,會將錯誤輸出到stderr上。
int main(int argc, char* argv[]); argc表示參數的個數,argv[]表示每個參數字符串。 對於./test -b "hello world" 命令,argc就為3,argv[]分別表示./test -b "hello world" , 實際上真正的參數從 -b 開始,也就是argv[1] ,所以optind的初始值就是1。
當執行getopt()函數時,會依次掃描每一個命令行參數(下標1開始),第一個-b是一個選項,而且這個選項在選項字符串optstring中有,b後面有冒號表示b後面必須帶有參數, “hello world”就是它的參數。所以這個命令行是符合要求的。至於執行後optind為什麽是3,這是因為optind是下一次getopt()函數要從argv[3]開始搜索。當然,這個例子argv[3]已經沒有了,此時getopt()函數會返回-1,結束while循環。
再次輸入一行命令: ./test -b "hello world" -c1234
輸出結果為:
optind:1, opterr:1 ----------------------------------------------------------- b the argument of -b is hello world 下一次起始搜索位置:optind = 3 ----------------------------------------------------------- c the argument of -c is 1234 下一次起始搜索位置:optind = 4 -----------------------------------------------------------
對於這個過程,最開始optind=1 ,找到選項-b 和他的參數“hello world” ,之後搜索起始位置跳至argv[3] 找到 -c和他的參數1234(選項和參數是連在一起的),由於-c1234是寫在一起的,所以他倆一起占用argv[3] ,之後搜索起始位置跳至 argv[4] ,而argv[4]為空,這樣getopt()函數就會返回-1,循環結束。
再次輸入命令: ./test -z 123
輸出結果為:
optind:1, opterr:1 ----------------------------------------------------------- ./test: invalid option -- ‘z‘ unknown option: z 下一次起始搜索位置:optind = 2 -----------------------------------------------------------
其中./test: invalid option -- ‘z‘ 就是輸出到stderr的錯誤輸出 ,如果把opterr設置為0那麽就不會有這條輸出。
再次輸入命令: ./test -zheng
輸出結果為:
optind:1, opterr:1 ----------------------------------------------------------- ./test: invalid option -- ‘z‘ unknown option: z 下一次起始搜索位置:optind = 1 ----------------------------------------------------------- ./test: invalid option -- ‘h‘ unknown option: h 下一次起始搜索位置:optind = 1 ----------------------------------------------------------- e the argument of -e is ng 下一次起始搜索位置:optind = 2 -----------------------------------------------------------
由於不帶參數的選項可以寫在一起,所以當getopt()函數找到-z的時候,發現在optstring中沒有,這時候他就認為h也是一個選項,也就是-h 和 -z寫在一起了,依次類推,直到找到-e,發現optstring中有。
Linux下 頭文件<getopt.h> 及其函數的應用