在Linux c語(yǔ)言開發(fā)時(shí),可使用getopt_long獲取命令行參數(shù)露筒,這個(gè)方法同時(shí)支持短選項(xiàng)和長(zhǎng)選項(xiàng),比較方便敌卓。(因?yàn)檫x項(xiàng)可以帶參數(shù),為了不和命令行參數(shù)混淆伶氢,這里命令行參數(shù)稱為選項(xiàng))
邊看代碼趟径,邊做分析:
#include <stdio.h>
#include <getopt.h> //需要包括此頭文件
// Values for long options
// 長(zhǎng)選項(xiàng)對(duì)應(yīng)的整數(shù)值瘪吏,在long_options結(jié)構(gòu)體數(shù)組中,對(duì)長(zhǎng)選項(xiàng)名對(duì)應(yīng)的整數(shù)值進(jìn)行定義
enum {
LONGOPT_VAL_TIMEOUT = 257, //注意我們定義的值從257開始蜗巧,是為了避開短選項(xiàng)
LONGOPT_VAL_MPORT
};
// 定義短選項(xiàng)掌眠,如果有必選參數(shù)就要在選項(xiàng)名后加冒號(hào),無(wú)參數(shù)或可選參數(shù)則不要
// 短選項(xiàng)的用法是一個(gè)-后面跟選項(xiàng)名幕屹,如果有參數(shù)空格加參數(shù)蓝丙,例如 ./myserver -c cfg.json
// 如果是可選參數(shù)則要使用兩個(gè)-,并用等號(hào)賦值,例如:./myserver --v=5
static const char *short_options = "c:vh";
// 長(zhǎng)選項(xiàng)的用法是兩個(gè)-后面選項(xiàng)名望拖,如果有參數(shù)需要看是必須參數(shù)還是可選參數(shù)渺尘。
// 定義長(zhǎng)選項(xiàng)數(shù)組,每一項(xiàng)是一個(gè)結(jié)構(gòu)體说敏,第一個(gè)成員是長(zhǎng)選項(xiàng)名鸥跟,第二個(gè)成員是參數(shù)使用情況,包括:
// required_argument:必須參數(shù)盔沫,在命令行中需要跟在選項(xiàng)名后面用空格分開医咨,例如 ./myserver --port 8000 或者用等號(hào)連接 ./myserver --port=8000
// no_argument: 沒(méi)有參數(shù),那么在選項(xiàng)之后就不能寫參數(shù)架诞,如果用等號(hào)加參數(shù)就會(huì)報(bào)錯(cuò) option '--help' doesn't allow an argument拟淮,如果空格加參數(shù),那參數(shù)會(huì)被認(rèn)為是一個(gè)選項(xiàng)谴忧。
// optional_argument: 可選參數(shù)很泊,只能使用等號(hào)添加。例如 ./myserver --verbose=5
// 結(jié)構(gòu)體第四個(gè)成員是選項(xiàng)對(duì)應(yīng)的整數(shù)值俏蛮。值得注意的是撑蚌,這里長(zhǎng)選項(xiàng)的整數(shù)值可以填入短選項(xiàng)的字符,這樣長(zhǎng)短選項(xiàng)可以關(guān)聯(lián)起來(lái)搏屑,達(dá)到相同的效果争涌。如果長(zhǎng)選項(xiàng)沒(méi)有對(duì)應(yīng)可用的短選項(xiàng),則這兒要定義一個(gè)數(shù)值辣恋,這個(gè)數(shù)值最好大于256亮垫,避免和短選項(xiàng)值沖突。下面會(huì)看到getopt_long返回值就是這個(gè)數(shù)值伟骨,通過(guò)這個(gè)數(shù)值進(jìn)行不同的操作饮潦。
static const struct option long_options[] = {
{"port", required_argument, NULL, 'p'},
{"timeout", required_argument, NULL, LONGOPT_VAL_TIMEOUT},
{"config", required_argument, NULL, 'c'},
{"verbose", optional_argument, NULL, 'v'},
{"help", no_argument, NULL, 'h'},
{NULL, 0, NULL, 0}
};
int main(int argc, char *argv[])
{
char *config_file = NULL;
char *port = NULL;
float timeout = 0.0f;
int verbose = 0;
int opt = 0;
while( (opt = getopt_long(argc, argv, short_options, long_options, NULL)) != -1){
switch (opt){
case 'h':
case '?': //如果是不能識(shí)別的選項(xiàng),則opt返回'?'
fprintf(stdout, "Usage: %s -p <port> [-v|--v <=verbose_level>] [-h]\n", argv[0]);
return 0;
case 'c':
config_file = optarg;
break;
case 'p': // 'p'是個(gè)短選項(xiàng)携狭,但是長(zhǎng)選項(xiàng)port的值也是'p'继蜡,所以這里同時(shí)處理了port
port = optarg;
break;
case LONGOPT_VAL_TIMEOUT: //長(zhǎng)選項(xiàng)timeout的值
timeout = atof(optarg);
break;
case 'v': // verbose有可選參數(shù),所以這兒判斷是否有參數(shù)
if(optarg == NULL){
verbose = 1;
}
else {
verbose = atoi(optarg);
}
break;
}
}
return 0;
}