本文首發于 2014-01-10 19:48:48
1. getopt
該函式用來決議命令列引數,
1.1. 函式定義
int getopt(int argc, char * const argv[], const char *optstring);
#include <unistd.h>
前兩個引數設為main函式的兩個引數,
optstring設為由該命令要處理的各個選項組成的字串,選項后面帶有冒號':'時,該選項是一個帶引數的選項,
舉例:
make -f filename -n
-f 是一個帶引數的選項,-n 是一個沒有引數的選項,可以像下面這樣呼叫
函式getopt來決議上面的例子,
c = getopt(argc, argv, "f:n");
此函式的回傳值即為當前找到的命令選項,全部選項都找到時的回傳值為-1,
通常一個命令有多個選項,為了取得所有選項,需要回圈呼叫此函式,直到回傳值為-1,
要使用此函式,還有幾個全域變數必須要了解:
extern char *optarg;
extern int optind, opterr, optopt;
/*
optarg: 當前選項帶引數時,optarg指向該引數,
optind: argv的索引,通常選項引數取得完畢時,通過此變數可以取得非選項引數(argv[optind])
optopt: 一個選項在argv中有,但在optstring中不存在時,或者一個帶引數的選項沒有引數時,
getopt()回傳'?',同時將optopt設為該選項,
opterr: 將此變數設定為0,可以抑制getopt()輸出錯誤資訊,
*/
1.2. 實體
#include <unistd.h>
#include <string.h>
#include <stdio.h>
int main(int argc, char *argv[ ])
{
int c;
int flg = 0;
char filename[256];
char testdata[256];
if (argc < 2)
{
printf("usage:%s [-f filename] [-n] testdata\n", argv[0]);
return -1;
}
opterr = 0;
while ((c = getopt(argc, argv, "f:n")) != -1)
{
switch (c)
{
case 'f':
strncpy(filename, optarg, sizeof(filename)-1);
break;
case 'n':
flg = 1;
break;
case '?':
default:
printf("usage:%s [-f filename] [-n] testdata\n", argv[0]);
return -1;
}
}
if (argv[optind] == NULL)
{
printf("usage:%s [-f filename] [-n] testdata\n", argv[0]);
return -1;
}
else
{
strncpy(testdata, argv[optind], sizeof(testdata)-1);
}
printf("fliename:%s flg:%d testdata:%s\n", filename, flg, testdata);
return 0;
}
2. getopt_long
這是支持長命令選項的函式,長選項以'--'開頭,
2.1. 函式定義
int getopt_long(int argc, char * const argv[],
const char *optstring,
const struct option *longopts, int *longindex);
#include <getopt.h>
前三個引數與函式getopt的引數是一樣的,
只支持長選項時,引數optstring設定為NULL或者空字串"",
第四個引數是一個構造體struct option的陣列,此構造體定義在頭檔案getopt.h中,此陣列的最后一個須將成員都置為0,
struct option {
const char *name;
int has_arg;
int *flag;
int val;
};
構造體各個成員的解釋如下:
name : 長選項的名字,
has_arg : no_argument或0表示此選項不帶引數,required_argument或1表示此選項帶引數,optional_argument或2表示是一個可選選項,
flag : 設定為NULL時,getopt_long()回傳val,設定為NULL以外時,>getopt_long()回傳0,且將flag設為val,
val : 回傳值或者flag的設定值,有些命令既支持長選項也支持短選項,可以通過設定此值為短選項實作,
第五個引數是一個輸出引數,函式getopt_long()回傳時,longindex的值是struct option陣列的索引,
關于回傳值有以下幾種情況:
識別為短選項時,回傳值為該短選項,
識別為長選項時,如果flag是NULL的情況下,回傳val,如果flag非NULL的情況下,回傳0,
所有選項決議結束時回傳-1,
存在不能識別的選項或者帶引數選項的引數不存在時回傳'?' ,
2.2. 實體
#include <stdio.h> /* for printf */
#include <stdlib.h> /* for exit */
#include <getopt.h>
int main(int argc, char **argv)
{
int c;
int digit_optind = 0;
int flag = 0;
while (1) {
int this_option_optind = optind ? optind : 1;
int option_index = 0;
static struct option long_options[] = {
{"add", required_argument, 0, 0 },
{"append", no_argument, 0, 0 },
{"delete", required_argument, 0, 0 },
{"verbose", no_argument, 0, 0 },
{"create", required_argument, 0, 'c'},
{"file", required_argument, 0, 'f'},
{0, 0, 0, 0 }
};
c = getopt_long_only(argc, argv, "abc:d:f:012", long_options, &option_index);
if (c == -1)
break;
switch (c) {
case 0:
printf("option %s", long_options[option_index].name);
if (optarg)
printf(" with arg %s", optarg);
printf("\n");
break;
case '0':
case '1':
case '2':
if (digit_optind != 0 && digit_optind != this_option_optind)
printf("digits occur in two different argv-elements.\n");
digit_optind = this_option_optind;
printf("option %c\n", c);
break;
case 'a':
printf("option a\n");
break;
case 'b':
printf("option b\n");
break;
case 'c':
printf("option c with value '%s'\n", optarg);
break;
case 'd':
printf("option d with value '%s'\n", optarg);
break;
case 'f':
printf("option f with value '%s'\n", optarg);
break;
case '?':
break;
default:
printf("?? getopt returned character code 0%o ??\n", c);
}
}
if (optind < argc) {
printf("non-option ARGV-elements: ");
while (optind < argc)
printf("%s ", argv[optind++]);
printf("\n");
}
exit(EXIT_SUCCESS);
}
歡迎關注我的微信公眾號【資料庫內核】:分享主流開源資料庫和存盤引擎相關技術,
| 標題 | 網址 |
|---|---|
| GitHub | https://dbkernel.github.io |
| 知乎 | https://www.zhihu.com/people/dbkernel/posts |
| 思否(SegmentFault) | https://segmentfault.com/u/dbkernel |
| 掘金 | https://juejin.im/user/5e9d3ed251882538083fed1f/posts |
| 開源中國(oschina) | https://my.oschina.net/dbkernel |
| 博客園(cnblogs) | https://www.cnblogs.com/dbkernel |
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/308193.html
標籤:C
