#include<unistd.h>
#include<getopt.h> /*所在头文件 */
// optarg —— 指向当前选项参数(如果有)的指针。
// optind —— 再次调用 getopt() 时的下一个 argv指针的索引。
// optopt —— 最后一个未知选项。
// opterr —— 如果不希望getopt()打印出错信息,则只要将全域变量opterr设为0即可。
extern char *optarg; /*系统声明的全局变量 */
extern int optind, opterr, optopt;
// 字符串optstring可以下列元素:
// 1.单个字符,表示选项。
// 2.单个字符后接一个冒号:表示该选项后必须跟一个参数。参数**紧跟在选项后**或者以**空格**隔开。该参数的指针赋给optarg。
// 3.单个字符后跟两个冒号:表示该选项后可以有参数也可以没有参数。如果没有跟参数,则optarg = NULL
// 如果有参数,**参数必须紧跟在选项后不能以空格隔开**。该参数的指针赋给optarg。(这个特性是GNU的扩张)。
// has_arg 指明是否带参数值,其数值可选:
// no_argument 表明长选项不带参数,如:--name, --help
// required_argument 表明长选项必须带参数,如:--prefix /root或 --prefix=/root
// optional_argument 表明长选项的参数是可选的,如:--help或 –prefix=/root,其它都是错误
struct option {
char *name; // name表示的是长参数名
int has_arg; // 有三个值
// no_argument(或者是0),表示该参数后面不跟参数值
// required_argument(或者是1),表示该参数后面一定要跟个参数值
// required_argument(或者是1)时,参数输入格式为:--参数 值 或者 --参数=值。
// optional_argument(或者是2),表示该参数后面可以跟,也可以不跟参数值
// optional_argument(或者是2)时,参数输入格式只能为:--参数=值。
int *flag; // 用来决定,getopt_long()的返回值到底是什么。
// 如果flag=null(通常情况),则函数会返回与该项option匹配的val值;
// 如果flag!=NULL,则将val值赋予flag所指向的内存,并且返回值设置为0。
int val; // 和flag联合决定返回值
};
// eg
static struct option long_options[] =
{
{"reqarg", required_argument,NULL, 'r'},
{"optarg", optional_argument,NULL, 'o'},
{"noarg", no_argument, NULL,'n'},
{NULL, 0, NULL, 0},
};
// fun: getopt是用来解析命令行选项参数的,但是只能解析短选项: -d 100,不能解析长选项:--prefix
// 包含 getopt 功能,增加了解析长选项的功能如:--prefix --help
// arg:
// argc:main()函数传递过来的参数的个数
// argv:main()函数传递过来的参数的字符串指针数组
// optstring:选项字符串,告知getopt()可以处理哪个选项以及哪个选项需要参数
//
// longopts:指明了长参数的名称和属性
// longindex:如果longindex非空,它指向的变量将记录当前找到参数符合longopts里的第几个元素的描述,
// 即是longopts的下标值
//
// ret: 对于短选项,返回值同getopt函数:
// *如果选项成功找到,返回选项字母;
// *如果所有命令行选项都解析完毕,返回 -1;
// *如果遇到选项字符不在 optstring 中,返回字符 '?';
// 如果遇到丢失参数,那么返回值依赖于 optstring 中第一个字符,
// 如果第一个字符是 ':' 则返回':',否则返回'?'并提示出错误信息。
// *对于长选项,如果flag是NULL,返回val,否则返回0;对于错误情况返回值同getopt函数
int getopt_long(int argc, char * const argv[], const char *optstring,
const struct option *longopts, int *longindex);
下边重点举例说明optstring的格式意义:
char*optstring = “ab:c::”;
单个字符a 表示选项a没有参数 格式:-a即可,不加参数
单字符加冒号b: 表示选项b有且必须加参数 格式:-b 100或-b100,但-b=100错
单字符加2冒号c:: 表示选项c可以有,也可以无 格式:-c200,其它格式错误
上面这个 optstring 在传入之后,getopt 函数将依次检查命令行是否指定了 -a, -b, -c
(这需要多次调用 getopt 函数,直到其返回-1),当检查到上面某一个参数被指定时,函数会返回被指定的参数名称(即该字母)
测试程序getopt
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main( int argc, char *argv[] )
{
int opt = 0;
static const char *optString = "ab:c::";
while ((opt = getopt(argc, argv, optString))!= -1)
{
printf("opt = %c\t\t", opt);
printf("optarg = %s\t\t",optarg);
printf("optind = %d\t\t",optind);
printf("argv[optind] = %s\n",argv[optind]);
}
return EXIT_SUCCESS;
}
特殊情况说明:
a. 出现不存在的参数
invalidoption – ‘e’
b. 缺少必须的参数
optionrequires an argument – ‘c’
c.???
如果在 optstring 中第一个字母加’:’,则最后丢失参数的那个选项 opt 返回的是’:’,不是’?’,并且没有提示错误信息,这里不再列出。
eg1 部分参数不出现
charoptString = “ab:c::”;
./test -b
./test: option requires an argument – ‘b’
opt = ? optarg = (null) optind = 2 argv[optind] = (null)
eg2 出现多余的参数
charoptstring = “ab:c::”;
./test -a100 -b100 -c200
opt = a optarg = (null) optind = 1 argv[optind] = -a100
./test: invalid option – ‘1’
opt = ? optarg = (null) optind = 1 argv[optind] = -a100
./test: invalid option – ‘0’
opt = ? optarg = (null) optind = 1 argv[optind] = -a100
./test: invalid option – ‘0’
opt = ? optarg = (null) optind = 2 argv[optind] = -b100
opt = b optarg = 100 optind = 3 argv[optind] = -c200
opt = c optarg = 200 optind = 4 argv[optind] = (null)
说明:
- 每一个需要加参数的变量都需要加上冒号!
- 出现非法变量,则返回
?
eg3 需要警惕,可能必须要变量的参数会自动把命令变为参数进行转化
charoptString = “ab:c::”;
./test -a -b -c200
opt = a optarg = (null) optind = 2 argv[optind] = -b
opt = b optarg = -c200 optind = 4 argv[optind] = (null)
而非强制参数则不会:
charoptString = “ab::c::”;
./test -a -b -c200
opt = a optarg = (null) optind = 2 argv[optind] = -b
opt = b optarg = (null) optind = 3 argv[optind] = -c200
opt = c optarg = 200 optind = 4 argv[optind] = (null)
测数程序getopt_long
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
#include <string.h>
int main( int argc, char *argv[] )
{
int opt;
int digit_optind = 0;
int option_index = 0;
static const char *optString = "a::b:c:d";
static struct option long_options[] =
{
{"reqarg", required_argument,NULL, 'r'},
{"optarg", optional_argument,NULL, 'o'},
{"noarg", no_argument, NULL,'n'},
{NULL, 0, NULL, 0},
};
while((opt =getopt_long(argc,argv,optString,long_options,&option_index))!= -1)
{
printf("opt = %c\t\t", opt);
printf("optarg = %s\t\t",optarg);
printf("optind = %d\t\t",optind);
printf("argv[optind] =%s\t\t", argv[optind]);
printf("option_index = %d\n",option_index);
}
return EXIT_SUCCESS;
}
required_argument(或者是1)时,参数输入格式为:–参数 值 或者 --参数=值。
optional_argument(或者是2)时,参数输入格式只能为:–参数=值。
长参数和短参数是两套系统.