一、命令行简介
解释分析命令行通常是所以程序的第一个任务,C语言通过argc和argv参数来访问它的命令行参数。
最简单的命令行处理技术可以通过if判断来表示,如下例:
- if(argc>1 && argv[1][0] ==‘-‘ && argv[1][1] ==‘h’) //判断命令行参数是否为-h
- {
- do _ some thing();
- }
这样处理简单有序的命令行还可以,对于复杂的命令行处理显得有心无力,于是GNU提供两个函数专门用来处理命令行参数:
getopt 和getopt_long
二、getopt函数
getopt() 函数声明如下:
- #include <unistd.h>
- int getopt(int argc, char *const argv[], const char *optstring);
-
- extern char *optarg;
-
- extern int optind, opterr, optopt;
说 明:
函数的argc和argv参数通常直接从main()的参数直接传递而来。optstring是选项字母组成的字串。如果该字串里的任一字符后面有冒号,那么这个选项就要求有选项参数。
当给定getopt()命令参数的数量 (argc)、指向这些参数的数组 (argv) 和选项字串 (optstring) 后,getopt() 将返回第一个选项,并设置一些全局变量。使用相同的参数再次调用该函数时,它将返回下一个选项,并设置相应的全局变量。如果不再有可识别的选项,将返回 -1,此任务就完成了。
getopt()所设置的全家变量包括:
optarg —- 当前选项参数字符(如果有的话)
optind —- argv的当前索引值。当getopt()在while循环中使用时,循环结束后,剩下的字串视为操作数,在
argv[optind]至argv[argc-1]中可以找到。
optopt —- 用于当发现无效选项字符的时候,getopt函数或者返回 “?” 或者返回 “:” 字符,并且optopt包含了
所发现的无效选项字符,或者当输入非法参数的时候,由optopt带回输入的非法参数(字符)
opterr —- 这个变量非零时,getopt()函数为“无效选项”和“缺少参数选项,并输出其错误信息。
另外:
如果optstring参数的第一个字符是冒号,那么getopt会根据错误情况返回不同的字符:
(1):当错误是无效选项,getopt返回 “?”
(2):当错误是缺少选项参数,getopt返回 “:”
(3): 无错误发生时,正常返回的是对应的字符!
注:GNU getopt()第三个特点是optstring中的选项字符后面接两个冒号,就允许该选项有可选的选项参数。在选项参数不存在的情况下,GNU getopt()返回选项字符并将optarg设置为NULL。
例子:
- #include<stdio.h>
- #include<unistd.h>
结果:
[root@localhost opts]# ./getopt -a
input para is a
optarg=(null).optind=2.opterr=1.optopt=0=[END]
[root@localhost opts]# ./getopt -a -b
input para is a
optarg=(null).optind=2.opterr=1.optopt=0=[END]
option b requires an argument
optarg=(null).optind=3.opterr=1.optopt=98=b[END]
[root@localhost opts]# ./getopt -a -b mingming
input para is a
optarg=(null).optind=2.opterr=1.optopt=0=[END]
input para is b,and optarg is mingming
optarg=mingming.optind=4.opterr=1.optopt=0=[END]
[root@localhost opts]# ./getopt -a -d
input para is a
optarg=(null).optind=2.opterr=1.optopt=0=[END]
option d is invalid:ignored
optarg=(null).optind=3.opterr=1.optopt=100=d[END]
三、getopt_long函数
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 (*flag = val, then return)
如果flag不是 NULL,但未发现长选项,那么它所指向的变量的数值不变。
返回值 | 含义 |
0 | getopt_long() 设置一个标志,它的值与 option 结构中的 val 字段的值一样 |
1 | 每碰到一个命令行参数, optarg 都会记录它 |
‘?’ | 无效选项 |
‘:’ | 缺少选项参数 |
‘x’ | 选项字符 ‘x’ |
-1 | 选项解析结束 |
- #include<stdio.h>
- #include<unistd.h>
结果:
[root@localhost opts]# ./getopt_long –ming mayer
getopt_long()return 109(m).
input para is m,and optarg is mayer
optarg=mayer.optind=3.opterr=1.optopt=0=[END]
do_all=0
do_help=0
do_version=0
do_file=(null)
m_input=mayer
[root@localhost opts]# ./getopt_long -m mayer
getopt_long()return 109(m).
input para is m,and optarg is mayer
optarg=mayer.optind=3.opterr=1.optopt=0=[END]
do_all=0
do_help=0
do_version=0
do_file=(null)
m_input=mayer
[root@localhost opts]# ./getopt_long -k
getopt_long()return 63(?).
option 107 is invalid:ignored
optarg=(null).optind=2.opterr=1.optopt=107=k[END]
do_all=0
do_help=0
do_version=0
do_file=(null)
m_input=(null)
[root@localhost opts]# ./getopt_long –mayer
getopt_long()return 63(?).
option 0 is invalid:ignored
optarg=(null).optind=2.opterr=1.optopt=0=[END]
do_all=0
do_help=0
do_version=0
do_file=(null)
m_input=(null)
[root@localhost opts]# ./getopt_long –ming
getopt_long()return 58(:).
option m requires an argument
optarg=(null).optind=2.opterr=1.optopt=109=m[END]
do_all=0
do_help=0
do_version=0
do_file=(null)
m_input=(null)
[root@localhost opts]# ./getopt_long –all
getopt_long()return 0().
0-0-0-0-0-0-0-0
optarg=(null).optind=2.opterr=1.optopt=0=[END]
do_all=1
do_help=0
do_version=0
do_file=(null)
m_input=(null)