在linux中,經常需要各種命令,通常情況下都會帶各種參數,而這些參數是如何解析的呢?
通常使用GNU C提供的函數getopt、getopt_long、getopt_long_only函數來解析命令行參數。
使用他們需要引用頭文件getopt.h。
原文地址:https://www.cnblogs.com/NickQ/p/11368656.html
1. getopt()函數
getopt()用來解析命令行選項參數的,但是只能解析短選項: -d 100,不能解析長選項:--prefix;其原型:
int getopt(int argc, char * const argv[],const char *optstring);
argc和argv和main函數的兩個參數一致,分別表示命令行參數個數和保存參數的字符串數組;
optstring,是短選項的規則聲明,形式如"a:b::cd:"
,分別表示程序支持的命令行短選項有-a、-b、-c、-d,冒號含義如下:
- 只有一個字符,不帶冒號——只表示選項, 如-c.
- 一個字符,后接一個冒號——表示選項后面帶一個參數,如-a 100 或 -a100.
- 一個字符,后接兩個冒號——表示選項后面帶一個可選參數,即參數可有可無,如果帶參數,則選項與參數直接不能有空格形式,應該型如-b200. 這里就能解釋為什么有時候帶參數需要空格,有時候確不需要空格的原因了. 很好理解,不需要空格是因為其參數可選,有空格的話沒法判斷其是否攜帶參數。
- 有時也會出現形如
:a:b::cd:
的optstring,其第一個字符是冒號表示如果參數解析過程中,出現參數丟失的情況,則返回值返回":",而不是"?"。方便后續程序區別是選項出錯還是參數出錯;
解析的原則根據函數返回值,循環調用該函數,直至該函數將參數解析完畢(返回值為-1).
具體的返回值描述是:
- 如果選項成功找到,返回選項字母;
- 如果遇到選項字符不在 optstring 中,返回字符 '?';
- 如果遇到丟失參數,那么返回值依賴於 optstring 中第一個字符,如果第一個字符是 ':' 則返回':',否則返回'?'並提示出錯誤信息。
- 如果所有命令行選項都解析完畢,返回 -1;
另外,在getopt.h中,也定義如下幾個全局變量。
char *optarg —— 指向當前選項參數(如果有參數的話)的指針。ps: 當前選項由返回值傳遞;
int optind —— 再次調用 getopt() 時的下一個 argv 指針的索引。
int optopt —— 最后一個未知選項。一般當出現未知選項,或缺少參數時,它就會保存這個未知選項。
int opterr —— 如果不希望getopt()打印出錯信息,則只要將該全局變量opterr設為0即可。
2. getopt_long()函數
getopt_long()是在getopt()的基礎上的拓展,可以獲取長參數,如獲取--help這種參數。其原型如下:
int getopt_long(int argc, char * const argv[], const char *optstring, const struct option *longopts, int *longindex);
同樣的,argc和argv和main函數的兩個參數一致,分別表示命令行參數個數和保存參數的字符串數組;optstring,是短選項的規則聲明;
不同的是getopt_long()有兩個解析長參數用到的參數變量;
- longopts 參數變量是用來描述長選項解析方案的,需要在調用前定義好;例如
static struct option longopts[] = {
{"help", no_argument, NULL, 'h'},
{"module", required_argument, NULL, 'm'},
{"set", required_argument, NULL, 's'},
{"get", no_argument, NULL, 'g'},
{"wakelock", required_argument, NULL, 'l'},
{"wakeunlock", required_argument, NULL, 'u'},
{0, 0, 0, 0}
};
這個option結構體,定義如下:
struct option
{
const char *name;//長選項名
int has_arg;//是否需要參數
int *flag;
int val;
};
- has_arg 指明是否帶參數值,其數值可選:
no_argument 表明長選項不帶參數,如:--name, --help
required_argument 表明長選項必須帶參數,如:--prefix /root 或 --prefix=/root
optional_argument 表明長選項的參數是可選的,如:--help 或 --prefix=/root,其它都是錯誤。 - flag和val相互依賴,主要分兩種情況:
(1). flag為NULL,val值用於確定該長選項,所以需要為長選項指定唯一的val值。這里也為長選項和短選項建立了橋梁。
(2). flag不為NULL,則將val值存放到flag所指向的存儲空間,用於標識該長選項出現過。
- longindex參數變量。如果longindex非空,它指向的變量將記錄當前找到參數符合longopts里的第幾個元素的描述,即是longopts的下標值。
3. getopt_long_only 函數
與 getopt_long 函數使用相同的參數表,在功能上基本一致,只是 getopt_long 只將 --name 當作長參數,但 getopt_long_only 會將 --name 和 -name 兩種選項都當作長參數來匹配。如果選項 -name 不能在 longopts 中匹配,但能匹配一個短選項,它就會解析為短選項。