分类: C/C++
2016-10-20 21:25:23
原型
int getopt_long(int argc,
定义的快捷键选项,如”hc:k::W;”,表示定义了3个快捷键选项-h, -c和-k。其中的c后边接一个冒号,表示c需要参数;k后边接两个冒号,表示k后边可以接参数,也可以不要参数。需要的所有快捷键必须在这里定义,否则其它快捷键将是非法的。 如果只有长选项,则optstring只能是空字符串"",不能是NULL。其中的”W;”选项由POSIX.2保留用于实现扩展,加上它的意思是可用-Whelp代--help选项。
如果选项前边有'+',如”+hc”,表示若出现参数前边没有选项的情况,则getopt_long()直接返回-1,不进行任何命令解析;如果选项前边有'-',如”-hc”, 表示若出现参数前边没有选项的情况,则将该参数视为一个选项,并且getopt_long()直接返回1;如果optstring最前边是':'(当有'+'或'-'时,':'应该在它们后边),比如”:hc”或者”+:hc”,则当选项未带参数时,getopt_long()返回':'。
短选项若需要参数,则两种表示方式,-h arg或者-harg,中间有无空格无所谓。
longopts是一个二维数组,数组的每个元素是一个定义好的选项数组。其原型如下:
struct option {
const char *name;
int
has_arg;
int
*flag;
int
val;
};
name表示长选项的名字,比如我们常用的--help的help。has_arg表示该选项后边是否应该接参数,0(或者no_argument)表示不跟参数,1(或者required_argument)表示必须跟参数,2(或者optional_argument)表示可以跟也可以不更参数。 flag是一个地址指针,若falg为0,则getopt_long()返回val值;若flag不为0,而是一个整型变量的地址,则getopt_long()返回0,且*flag=val。
长选项若需要参数,则两种表示方式,--help arg或者--help=arg。
当longindex不为NULL时,*longindex指向一个整型变量。当解析过长选项时,*longindex的值就是该长选项在longopts数组的位置。
(1)optstring和longopts一个表示短选项命令,一个表示长选项命令,他们是不相关的。可以只有长选项,也可以只有短选项。
(2)getopt_long()函数,每解析一个选项,在argv数组中的参数顺序就会变动一次,被解析过的选项(包括需要参数的选项的参数)会排到argv数组的前边,未解析过的选项和参数会排到后边。当解析完所有选项之后,没有选项的参数会全部排到argv数组的最后。
测试代码
即替换const char * opt_string = "hs:v::W;";
(1)-h选项,无参数
[root@192 ch-16]# ./main -h (1) argv: ./main -h
(2) [1] optind[2] argv: ./main -h getoption:< -h >
[2] break
(3) argv: ./main -h |
(2)-s选项,有参数
[root@192 ch-16]# ./main -s kk (1) argv: ./main -s kk
(2) [1] optind[3] argv: ./main -s kk getoption:< -s , kk> #optarg获得了参数
[2] break
(3) argv: ./main -s kk |
-s选项,无参数,getopt_long()返回?,且打印一句错误信息
[root@192 ch-16]# ./main -s (1) argv: ./main -s
(2) [1] ./main: option requires an argument -- 's' #打印的需要参数的错误信息 optind[2] argv: ./main -s error opt[s], invalid option #返回问号, 错误选项在optopt全局变量中 |
(3)-v 参数可选选项,有参数。解析完之后,optind全局变量指向了abc参数。这里很奇怪,因为-v是可选参数,既然添加了参数就应该将abc视为-v的参数。而最后optind指向了abc,表示在这里将-v视为了无参数选项。
[root@192 ch-16]# ./main -v abc (1) argv: ./main -v abc
(2) [1] optind[2] abc argv: ./main -v abc getoption:< -v >
[2] break
(3) argv: ./main -v abc optind[2] abc #abc被视为了无选项的参数 |
-v 参数选项可选,无参数。
[root@192 ch-16]# ./main -v (1) argv: ./main -v
(2) [1] optind[2] argv: ./main -v getoption:< -v >
[2] break
(3) argv: ./main -v |
测试 ‘:’
即替换const char * opt_string = ":hs:v::W;";
(1)-s 参数必选参数选项,无参数。因为opt_string最前边有冒号,所以当必选参数选项未带参数时,getopt_long()函数并不返回’?’,而是返回’:’
[root@192 ch-16]# ./main -s (1) argv: ./main -s
(2) [1] optind[2] argv: ./main -s opt[s], missing option argument ':' #必选参数选项-s未带参数,getopt_long()函数返回冒号 |
测试 ‘+’
即替换const char * opt_string = "+:hs:v::W;";
(1)-s 参数必选参数选项,无参数。因为opt_string最前边有冒号,且冒号在+号之后,所以当必选参数选项未带参数时,getopt_long()函数并不返回’?’,而是返回’:’
[root@192 ch-16]# ./main –s (1) argv: ./main -s
(2) [1] optind[2] argv: ./main -s opt[s], missing option argument ':' #必选参数选项-s未带参数,getopt_long()函数返回冒号 |
(2)因为opt_string最前边有’+’号,所以当出现参数时,getopt_long()函数并不返回直接返回-1。从下边的例子可以看到abc后边的-h没有执行,就直接返回-1了。
[root@192 ch-16]# ./main abc -h (1) argv: ./main abc -h
(2) [1] break #直接返回-1,退出
(3) argv: ./main abc -h optind[1] abc optind[2] -h |
测试 ‘-’
即替换const char * opt_string = "-:hs:v::W;";
(1)当短选项最前边有’-’时,getopt_long()会将没有选项的参数视为选项,且getopt_long()会返回1。
[root@192 ch-16]# ./main abc -h (1) argv: ./main abc -h
(2) [1] optind[2] -h argv: ./main abc -h getoption:< - > # 这个输出是当getopt_long()返回1时输出的
[2] optind[3] argv: ./main abc -h getoption:< -h >
[3] break
(3) argv: ./main abc -h |
测试长选项
即替换const char * opt_string = "hs:v::W;";
(1)--go2 和 --size,这两个选项在longopts中的has_tag和flag字短都为0,表示都不需要参数且getopt_long()返回都是val字段。由于val字段都是’g’,所以返回都相同。
[root@192 ch-16]# ./main --go2 --size (1) argv: ./main --go2 --size
(2) [1] optind[2] --size argv: ./main --go2 --size getoption:< --go2 > or < --size > #返回了’g’时的打印
[2] optind[3] argv: ./main --go2 --size getoption:< --go2 > or < --size > #返回了’g’时的打印
[3] break
(3) argv: ./main --go2 --size |
(2)当短选项中有W;时,长选项比如--go2可以由-Wgo2表示
[root@192 ch-16]# ./main --go2 -Wgo2 (1) argv: ./main --go2 -Wgo2
(2) [1] optind[2] -Wgo2 argv: ./main --go2 -Wgo2 getoption:< --go2 > or < --size >
[2] optind[3] argv: ./main --go2 -Wgo2 getoption:< --go2 > or < --size > #-Wgo2与-go2返回结果相同
[3] break
(3) argv: ./main --go2 -Wgo2 |
(3)--go3必带参数,返回’o’; --unin参数可选,但这里不知为何,添加参数依然未生效,--unin被当做了没有参数的选项。
[root@192 ch-16]# ./main --unin y --go3 x (1) argv: ./main --unin y --go3 x
(2) [1] optind[2] y argv: ./main --unin y --go3 x getoption:< --unin >
[2] optind[5] argv: ./main --unin y --go3 x getoption:< --go3 , x>< longindex, 1>
[3] break
(3) argv: ./main --unin --go3 x y optind[4] y #optind最后指向了y,说明—unin被当成了无参数选项处理 |
(4)--event1、--event2和--event3的flag字段都是一个整型变量的地址,所以getopt_long()返回0,且val字段的值被赋给flag指向的地址空间。
[root@192 ch-16]# ./main --event1 x --event2 --event3 y (1) argv: ./main --event1 x --event2 --event3 y
(2) [1] optind[3] --event2 argv: ./main --event1 x --event2 --event3 y getoption:< flag = 0 , A1>
[2] optind[4] --event3 argv: ./main --event1 x --event2 --event3 y getoption:< flag = 1 , A2>
[3] optind[6] argv: ./main --event1 x --event2 --event3 y getoption:< flag = 2 , A3>
[4] break
(3) argv: ./main --event1 x --event2 --event3 y |