getopt函数和getopt_long函数学习笔记
1.头文件
1. #include <stdio.h>
2. #include <stdlib.h>
3. #include <unistd.h>
4. #include <getopt.h>
2.函数原型
int getopt_long(int argc, char * const argv[], const char *optstring, const struct option *longopts, int *longindex);
longindex参数如果没有设置为NULL,那么它就指向一个变量,这个变量会被赋值为寻找到的长选项在longopts中的索引值
3.全局符号
(1)
1. struct option {
2. char *name;
3. int has_arg;
4. int *flag;
5. int val;
6. };
一般每个长选项都对应一个短选项,两者是等价的,option结构就是用来定义长选项对应哪个短选项,name表示长选项的名称,val表示对应的短选项,比如{ "no-proxy", no_argument, NULL, 'N' },说明--no-proxy对应与-N。
has_arg可以取值如下:
no_argument 0 选项没有参数
requierd_argument 1 选项需要参数
optional_argument 2 选项参数可选
比如我们可以定义如下选项:
1. static const struct option longopts[] = { 2. { "no-proxy", no_argument, NULL, 'N' }, 3. { "output", required_argument, NULL, 'o' }, 4. { "user-agent", required_argument, NULL, 'U' }, 5. { "verbose", no_argument, NULL, 'v' }, 6. { "quiet", no_argument, NULL, 'q' }, 7. { "help", no_argument, NULL, 'h' }, 8. { "version", no_argument, NULL, 'V' }, 9. { NULL, no_argument, NULL, 0 } 10. };
1. extern char *optarg
2. extern int optind, optopt, opterr
假设使用下载工具axel:
axel -q --no-proxy --max-speed=150 http://blog.csdn.net/kenby/index.html
初始时,optind的值为1,指向第1个参数,每调用一次getopt_long,optind就向后移一个单位,指向第二个参数,这样optind总是指向下一个要处理的参数,optarg表示参数的值,比如但处理max-speed时,optarg的值为150
4.函数返回值
(1)若没有命令行参数,返回-1
(2)若碰到匹配的短选项, 返回对应的字符,比如碰到-N, 返回'N',若碰到匹配的长选项,返回在option数组里面定义的val,
比如碰到--no-proxy, 返回'N'。
(3)若碰到无法识别的短选项,返回-1, 若碰到无法识别的长选项,返回'?'
#################################################################
Linux系统下,需要大量的命令行选项,如果自己手动解析他们的话实在是有违软件复用的思想,不过还好,GNU C library留给我们一个解析命令行的接口(X/Open规范),好好使用它可以使你的程序改观不少。
使用getopt_long()需要引入头文件
#include <getopt.h>
现在我们使用一个例子来说明它的使用。
一个应用程序需要如下的短选项和长选项。
短选项 长选项 作用
-h --help 输出程序命令行参数说明然后退出
-o filename --output filename 给定输出文件名
-v --version 显示程序当前版本后退后
为了使用getopt_long函数,我们需要先确定两个结构:
1.一个字符串,包括所需要的短选项字符,如果选项后有参数,字符后加一个":"符号。本例中,这个字符串应该为"ho:v"。(因为-o后面有参数filename,所以字符后面要加":")
2.一个包含长选项字符串的结构体数组,每一个结构体包含4个域,第一个域为长选项字符串,第二个域是一个标识,只能为0或1,分别代表没有、有。 第三个域永远为NULL。第四个域为对应的短选项字符串。结构体数组的最后一个元素全部为NULL和0,标识结束。在本例中,它应该像一下的样子:
const struct option long_options[] = { { "help", 0, NULL, 'h' }, { "output", 1, NULL, 'o' }, { "version", 0, NULL, 'v' }, { NULL, 0, NULL, 0} };
调用时需要把main的两个参数argc和argv以及上述两个数据结构传给getopt_long。
每次调用getopt_long,它会解析一个符号,返回相应的短选项字符,如果解析完毕返回-1。所以需要使用一个循环来处理所有的参数,而相应的循环 里会使用switch语句进行选择。如果getopt_long遇到一个无效的选项字符,它会打印一个错误消息并且返回'?',很多程序会打印出帮助信息 并且中止运行;当getopt_long解析到一个长选项并且发现后面没有参数则返回':',表示缺乏参数。当处理一个参数时,全局变量optarg指向 下一个要处理的变量。当getopt_long处理完所有的选项后,全局变量optind指向第一个未知的选项索引。
这一个例子代码为下:
/
/编译使用gcc -o getopt_long getopt_long.c #include <getopt.h> #include <stdio.h> #include <stdlib.h> /*程序的名字*/ const char* program_name; /* 打印程序参数 */ void print_usage (FILE* stream, int exit_code) { fprintf (stream, "Usage: %s options [ inputfile ... ]\n", program_name); fprintf (stream, " -h --help 显示这个帮助信息.\n" " -o --output filename 将输出定位到文件.\n" " -v --version 打印版本信息.\n"); exit (exit_code); } /* 主程序 */ int main (int argc, char* argv[]) { int next_option;//下一个要处理的参数符号 int haveargv = 0;//是否有我们要的正确参数,一个标识 /* 包含短选项字符的字符串,注意这里的‘:’ */ const char* const short_options = "ho:v"; /* 标识长选项和对应的短选项的数组 */ const struct option long_options[] = { { "help", 0, NULL, 'h' }, { "output", 1, NULL, 'o' }, { "version", 0, NULL, 'v' }, { NULL, 0, NULL, 0 }};//最后一个元素标识为NULL /* 此参数用于承放指定的参数,默认为空 */ const char* output_filename = NULL; /* 一个标志,是否显示版本号 */ int verbose = 0; /* argv[0]始终指向可执行的文件文件名 */ program_name = argv[0]; do { next_option = getopt_long (argc, argv, short_options, long_options, NULL); switch (next_option) { case 'h': /* -h or --help */ haveargv = 1; print_usage (stdout, 0); case 'o': /* -o or --output */ /* 此时optarg指向--output后的filename */ output_filename = optarg; haveargv = 1; break; case 'v': /* -v or --version */ verbose = 1; haveargv = 1; break; case ':': /* 缺乏长选项内容 */ break; case '?': /* 出现一个未指定的参数*/ print_usage (stderr, 1); case -1: /* 处理完毕后返回-1 */ if (!haveargv) { print_usage (stderr, 1); } break; default: /* 未指定的参数出现,出错处理 */ print_usage (stderr, 1); break; } }while (next_option !=-1); if (verbose) { //假如这样运行程序,。./demo_getopt -v 123 //结果输出:123 int i; for (i = optind; i < argc; ++i) printf ("Argument: %s\n", argv[i]); } return 0; }