每一天你都在使用大量的命令行程序,是不是感覺那些命令行參數用起來比較方便,他們都是使用getopt來實現的。
在Linux下使用getopt寫程序是一種比較cool的事情,下面來簡單的介紹一下getopt的使用。
=== getopt使用 ===
在討論參數處理之前,我們先明確兩個概念:選項、選項參數
gcc -g -o test test.c
我們經常使用上面的命令來編譯程序,這裡g和o就是選項,其中test就是o的選項參數
下面我們來看一下getopt:
首先是函數聲明:
#include <unistd.h>
extern char *optarg;
extern int optind;
extern int optopt;
extern int opterr;
extern int optreset;
int getopt(int argc, char * const *argv, const char *optstring);
直接看一個例子:
/* getopt.c */
#include <unistd.h>
#include <stdio.h>
int main(int argc, char * argv[])
{
int aflag=0, bflag=0, cflag=0;
int ch;
while ((ch = getopt(argc, argv, "ab:c")) != -1)
{
printf("optind: %d\n", optind);
switch (ch) {
case 'a':
printf("HAVE option: -a\n");
aflag = 1;
break;
case 'b':
printf("HAVE option: -b\n");
bflag = 1;
printf("The argument of -b is %s\n", optarg);
break;
case 'c':
printf("HAVE option: -c");
cflag = 1;
break;
case '?':
printf("Unknown option: %c\n",(char)optopt);
break;
}
}
}
通過上面的例子,大家應該可以照貓畫虎,就可以在自己的程序中使用getopt函數了。
getopt()每調用一次返回一個選項。
argc 和 argv 很顯然就是 main 函數的兩個參數。
字符串 optstring 可以包含下列元素:單個字符,字符後面接一個冒號說明後面跟隨一個選項參數,字符後面接兩個冒號說明後面跟隨一個可有可無的選項參數。例如,一個選項字符 "x" 表示選項 "-x" ,選項字符 "x:" 表示選項和其參數 "-x argument",選項字符 "x::" 表示選項 x 的參數是可選的(“::” 是 GNU 增加的,不一定在所有的UNIX 系統下都可以使用)。
getopt()的返回後,如果有選項參數的話 optarg 指向選項參數,並且變量 optind 包含下一個 argv 參數作為對 getopt() 下一次調用的索引。變量 optopt 保存最後一個由 getopt() 返回的已知的選項。
當參數列已經到結尾時getopt()函數返回-1,當遇到一個未知的選項時 getopt 返回'?'。參數列中選項的解釋可能會被'--'取消,由於它引起 getopt()給參數處理發送結束信號並返回-1。
很多時候,我們不希望輸出任何錯誤信息,或更希望輸出自己定義的錯誤信息。可以采用以下兩種方法來更改getopt()函數的出錯信息輸出行為:
在調用getopt()之前,將opterr設置為0,這樣就可以在getopt()函數發現錯誤的時候強制它不輸出任何消息。
如果optstring參數的第一個字符是冒號,那麼getopt()函數就會保持沉默,並根據錯誤情況返回不同字符,如下:
“無效選項” ―― getopt()返回'?',並且optopt包含了無效選項字符(這是正常的行為)。
“缺少選項參數” ―― getopt()返回':',如果optstring的第一個字符不是冒號,那麼getopt()返回'?',這會使得這種情況不能與無效選項的情況區分開。
例如optstring為:a:b::c,表示a帶一個參數,b可選,c不帶參數
如果輸入d,“無效選項“,getopt返回'?'
如果輸入的a忘記帶參數,“缺少選項參數”,getopt應返':' ;如果不再optstring的第一個字符不是':'的話,那麼將會把這個錯當成"無效參數",從而getopt返回'?';從而無法區別錯誤類型
比如:
wangyao@fisherman:~/Desktop/Advanced Linux Programming/ALP-listings/Trainning$ ./getopt -a -d -b foo
optind: 2
HAVE option: -a
./getopt: invalid option -- d
optind: 3
Unknown option: d
optind: 5
HAVE option: -b
The argument of -b is foo
wangyao@fisherman:~/Desktop/Advanced Linux Programming/ALP-listings/Trainning$ ./getopt -a -- -c -b foo
optind: 2
HAVE option: -a
getopt 的源代碼在下面,getopt 將只會解釋到 -a。
變量opterr和optind都被初始化為1。如果想要略去命令行的前幾個參數,可以在調用getopt()前將optind設成其他值。
如果不希望getopt()輸出出錯信息,將全域變量 opterr 設為 0 即可。
是不是使用比較簡單啊!
=== getopt_long使用 ===
我敢說,幾乎每個人在接觸到一個新的命令的時候,第一件干的事情就是 cmd -h 或者是 cmd --help,-h我們都知道是使用getopt來實現的,那麼--help是怎麼實現的呢?那就是getopt_long了,他可以支持長參數
先看一個例子程序:
#include <stdio.h>
#include <getopt.h>
int do_name, do_gf_name;