平时写程序时,有时需要对命令行参数进行处理。在接触本文所涉及的内容前,我们可能想到的方法是顺序提取命令行参数,进行顺序判断处理;然而,这种方法相当不灵活,尤其是在遇到带有可选参数的情况时,很难处理。为此,Linux提供了如下接口进行命令行参数的处理:
#include <unistd.h>
int getopt(int argc, char * const argv[],const char *optstring);
extern char *optarg;
extern int optind, opterr, optopt;
#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); optarg; //指向当前选项参数(如果有)的指针
optind, //再次调用 getopt() 时的下一个 argv 指针的索引
opterr, //指定getopt、getopt_long、getopt_long_only是否在遇到错误时将错误输出到标准输出流
optopt; //最后一个未知选项int getopt(int argc, char * const argv[],const char *optstring);argc和argv与main函数的两个参数相匹配的
#include <stdio.h>
#include <unistd.h>
int main(int argc, char* argv[])
{
int opt;
char *optstring = "a:b::cd:";
while ((opt = getopt(argc, argv, optstring)) != -1)
{
printf("opt = %c\n", opt);<span style="white-space:pre"> </span> //输出选项名称
printf("optarg = %s\n", optarg); //输出选项后接的参数
printf("optind = %d\n", optind); //输出当前命令行参数下一个参数的下标
printf("argv[optind-1] = %s\n\n", argv[optind-1]); //
}
return 0;
}
测试windeal@ubuntu:Test$ ./a.out -a 100 -b200 -b -c -d 300 opt = a optarg = 100 optind = 3 argv[optind-1] = 100 opt = b optarg = 200 optind = 4 argv[optind-1] = -b200 opt = b optarg = (null) optind = 5 argv[optind-1] = -b opt = c optarg = (null) optind = 6 argv[optind-1] = -c opt = d optarg = 300 optind = 8 argv[optind-1] = 300 windeal@ubuntu:Test$
getopt_long相当于getopt的拓展,getopt_long支持长选项参数(即选项不是单个字符)。
getopt_long其原型如下:
int getopt_long(int argc, char * const argv[],
const char *optstring,
const struct option *longopts, int *longindex);
除了与getopt相同的三个参数外,getopt_long还带有参数longopts,和longindex。
longindex表示当前长参数在longopts中的索引值
longopts类型定义如下
struct option {
const char *name;
int has_arg;
int *flag;
int val;
};
required_argument(或者是1)时 ——参数输入格式为:--参数 值 或者 --参数=值。
optional_argument(或者是2)时 ——参数输入格式只能为:--参数=值。
#include <stdio.h>
#include <unistd.h>
#include <getopt.h>
#define VAL1 0
#define VAL2 1
#define VAL3 2
int main(int argc, char* argv[])
{
int opt;
int this_option_optind = optind ? optind : 1;
char *optstring = "a:b::cd:";
struct option long_options[] = {
{"lopt1", no_argument, 0, VAL1},
{"lopt2", required_argument, 0, VAL2},
{"lopt3", optional_argument, 0, VAL3},
{"lopt4", no_argument, 0, VAL1},
{0,0,0,0}
};
int option_index = 0;
while ((opt = getopt_long(argc, argv, optstring, long_options, &option_index)) != -1)
{
switch(opt)
{
case VAL1:
case VAL2:
case VAL3:
printf("option %s", long_options[option_index].name);
if (optarg)
printf(" with arg %s", optarg);
printf("\n");
break;
case 'a':
case 'b':
case 'c':
case 'd':
printf("opt = %c\n", opt); //输出选项名称
printf("optarg = %s\n", optarg); //输出选项后接的参数
printf("optind = %d\n", optind); //输出当前命令行参数下一个参数的下标
printf("argv[optind-1] = %s\n\n", argv[optind-1]); //
default:
exit(-1);
break;
}
}
return 0;
}
测试结果:
windeal@ubuntu:Test$ ./a.out --lopt1 --lopt2 23 --lopt3=33 --lopt4 -a 100 option lopt1 option lopt2 with arg 23 option lopt3 with arg 33 option lopt4 opt = a optarg = 100 optind = 8 argv[optind-1] = 100 windeal@ubuntu:Test$ vim test.c
getopt_long_only与getopt_long参数表和功能基本相同,主要差别的地方在于长选项参数的解析。
在getopt_long中,长选项参数需要由双横杠开始,即--name, 而-name会被解析成-n,-a,-m和-e在optstring中匹配
在getopt_long_only中,--name和-name都被解析成长选项参数。
getopt、getopt_long、getopt_long_only详解
原文地址:http://blog.csdn.net/windeal3203/article/details/44097119