1.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()每调用一次返回一个选项。 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()返回'?',这会使得这种情况不能与无效选项的情况区分开。
#include <stdio.h>
#include <unistd.h>
#include <getopt.h>
#include <iostream.h>
int main(int argc, char * argv[])
{
int aflag=0, bflag=0, cflag=0;
int ch;
/*a后面的冒号(:),表示a必须有参数输入,b,c同理.同时参数3也限制了合法的参数为abc*/
while ((ch = getopt(argc, argv, "a:b:c:")) != -1)
{
printf("输入了参数的个数为:%d/n",optind);
switch(ch)
{
case 'a':
aflag = 1;
printf("The argument of -a is %s/n", optarg);
break;
case 'b':
bflag = 1;
printf("The argument of -b is %s/n", optarg);
break;
case 'c':
cflag = 1;
printf("The argument of -c is %s/n", optarg);
break;
case '?':
/*如果输入了abc以外的参数,那么getopt将返回问号*/
printf("Unknown option: %c/n",(char)optopt);
break;
}
}
}
getopt_long用来处理长选项,使用 man 3 getopt_long ,得到其声明如下:
- #include <getopt.h>
- int getopt_long(int argc, char * const argv[], const char *optstring,
- const struct option *longopts, int *longindex);
- int getopt_long_only(int argc, char * const argv[], const char *optstring,
- const struct option *longopts, int *longindex);
前三个参数与getopt相同,下一个参数是指向数组的指针,这个数组是option结构数组,option结构称为长选项表,其声明如下:
- struct option
- {
- const char *name;
- int has_arg;
- int *flag;
- int val;
- };
结构中的元素解释如下:
const char *name :选项名,前面没有短横线
int has_arg:描述长选项是否有参数,其值见下表
符号常量 | 数值 | 含义 |
no_argument required_argument optional_argument | 0 1 2 | 选项没有参数 选项需要参数 选项参数是可选的 |
int *flag:
如果该指针为NULL,那么getopt_long返回val字段的值;
如果该指针不为NULL,那么会使得它所指向的结构填入val字段的值,同时getopt_long返回0
int val:
如果flag是NULL,那么val通常是个字符常量,如果短选项和长选项一致,那么该字符就应该与optstring中出现的这个选项的参数相同;
- #include <stdio.h>
- #include <unistd.h>
- #include <getopt.h>
- char *para = ":ab:cf:v";
- int do_all = 0;
- int do_help = 0;
- int do_version = 0;
- char *file = NULL;
- struct option longopt[] =
- {
- {"all", no_argument, &do_all, 1},
- {"file", required_argument, NULL, 'f'},
- {"help", no_argument, &do_help, 1},
- {"version", no_argument, &do_version, 1},
- {"bob", required_argument, NULL, 'b'},
- {0, 0, 0, 0},
- };
- int main(int argc, char *argv[])
- {
- int oc = -1;
- char *b_input = NULL;
- while((oc = getopt_long(argc, argv, para, longopt, NULL)) != -1)
- {
- switch(oc)
- {
- case 'a':
- printf("input para is a/n");
- break;
- case 'b':
- b_input = optarg;
- printf("input para is b,and optarg is %s/n", b_input);
- break;
- case 'c':
- printf("input para is c/n");
- break;
- case 'v':
- printf("input para is v/n");
- break;
- case 'f':
- printf("input para is f/n");
- file = "hello world";
- break;
- case 0:
- break;
- case ':':
- printf("option %c requires an argument/n",optopt);
- break;
- case '?':
- default:
- printf("option %c is invalid:ignored/n",optopt);
- break;
- }
- }
- printf("do_all is %d/n",do_all);
- printf("do_help is %d/n",do_help);
- printf("do_version is %d/n",do_version);
- printf("do_file is %s/n",file);
- printf("bob is %s/n", b_input);
- return 0;
- }
执行的结果: 只显示关键结果
[root@heguangwu projects]# ./opt_ex2 -a
input para is a
[root@heguangwu projects]# ./opt_ex2 --all
do_all is 1
[root@heguangwu projects]# ./opt_ex2 -f h
input para is f
do_file is hello world
[root@heguangwu projects]# ./opt_ex2 --bob aa
input para is b,and optarg is aa
bob is aa
[root@heguangwu projects]# ./opt_ex2 -b aa
input para is b,and optarg is aa