剛開始接觸 一些處理命令行參數的操作,開始不太明白,用例子測試了一下,感覺比以前明瞭多了。
命令行參數有長參數如version, 還有短參數 如 v, 那麼用這兩個都可以。程序處理的時候,會首先把長參數轉換成對應的短參數,如會把version轉成v, 再進行 v 對應的操作就可以了。
命令行參數的選項,有的需要參數,有的不需要參數,或者有的參數是可選的,那麼怎麼區分呢?
首先,對這些選項,如何組織起來? 是以字符串的形式組織起來了。如我有一個程序,有兩個選項,-a, -b, 我輸入的時候是 ./a.out -a -b, 那麼中間會處理成這種 ab這種字符串的形式,這個字符串就是所有的命令行的輸入選項。區別是否有參數就在於此。如果某個選項必須有參數,則這一選項後有一個參數,如果參數是可選的,則其後面有兩個冒號。如
-a 是沒有參數的, -b 後面必須有參數, -c 後面是否有參數是可選的。則短的命令行選項是: ab:c::
下面我們通過一個簡單的例子看一下。
#include <stdio.h>
#include <unistd.h>
#include <getopt.h>
char *l_opt_arg;
char* const short_options = "myl:";
//char* const short_options = "nbl:";
struct option long_options[] = {
{ "name", 0, NULL, 'm' }, //長選項對應的短選項參數, 第二個0表示選項後面無參數, 1爲有參數,2爲可選
{ "yourname", 0, NULL, 'y' },
{ "love", 1, NULL, 'l' },
{ 0, 0, 0, 0},
};
int main(int argc, char *argv[])
{
int c, i;
printf("before:\n");
for (i=1; i<argc; i++)
printf("arg:%d : %s\n", i, argv[i]);
printf("\n");
while((c = getopt_long (argc, argv, short_options, long_options, NULL)) != -1)
{
// printf("optind:%d, %c \n", optind, c);
switch (c)
{
case 'm':
printf("My name is A.\n");
break;
case 'y':
printf("His name is B.\n");
break;
case 'l':
l_opt_arg = optarg;
printf("Our love is %s!\n", l_opt_arg);
break;
}
}
printf("optind:%d\n", optind);
printf("after:\n");
for (i=1; i<argc; i++)
printf("arg:%d : %s\n", i, argv[i]);
return 0;
}
注意,此程序可接收的的選項有三個, 一個是m ,不帶參數, y 不帶參數, l 要求有參數。
那如果-m 不帶參數,如果我寫了參數,會怎麼樣呢?下面看測試
在調用 getopt_long 以後, optind 的值隨之變化 。在while循環後,我們再把開始的命令行參數打印出來,看一下有什麼不同。把上面的代碼命名爲: getopt_long.c
編譯,可執行文件爲 a.out
$ gcc getopt_long.c
$ ./a.out -m -y
before:
arg:1 : -m
arg:2 : -y
My name is A.
His name is B.
optind:3
after:
arg:1 : -m
arg:2 : -y
$ ./a.out -m -y -l banana
before:
arg:1 : -m
arg:2 : -y
arg:3 : -l
arg:4 : banana
My name is A.
His name is B.
Our love is banana!
optind:5
after:
arg:1 : -m
arg:2 : -y
arg:3 : -l
arg:4 : banana
$./a.out -m lisi -y zhangsan -l banana aaa
before:
arg:1 : -m
arg:2 : lisi
arg:3 : -y
arg:4 : zhangsan
arg:5 : -l
arg:6 : banana
arg:7 : aaa
My name is A.
His name is B.
Our love is banana!
optind:5
after:
arg:1 : -m
arg:2 : -y
arg:3 : -l
arg:4 : banana
arg:5 : lisi
arg:6 : zhangsan
arg:7 : aaa
注意 argv 裏面值的順序已經和原來不一樣了,對命令行的參數重新組織了一下順序,也就是不認識的命令行參數,都放在了argv的最後,其中 optind 指向了這些沒有被解釋的參數的第一個。
optind有作用吧!如果你想輸出哪些命令行參數沒有被識別,可以打印出來 for (i=optind; i<argc; i++) printf("%s\n", argv[i]); 即可
附:如果是長參數,則使用 --, 如 --help, 因爲 -help時,(選項不需要參數的情況) 會把它當成 四個選項, -h -e -l -p. 所以使用長參數時,要用兩個 橫線 --