我的my_ls源代码地址:https://github.com/gaopu/my_ls
获取程序运行时用户输入的参数
例如运行ls时输入的-a,-l,这些就是参数,还有一种长参数例如--help,-help。
getopt_long_only()也是在上一个函数基础上有所增加,输入长参数可以不用输入两个--,而是这样:-help
int getopt_long_only(int argc, char * const argv[],const char *optstring,const struct option *longopts, int *longindex)
我感觉直接上例子能更快上手使用,那就拿ls 这个例子来写一个获取参数的循环:
//录入参数 char opt; opterr = 0; //不显示参数错误信息 while ((opt = getopt(argc,argv,"alRtS")) != -1) { if (opt == 'a') { param |= PARAM_a; } else if (opt == 'l') { param |= PARAM_l; } else if (opt == 'R') { param |= PARAM_R; } else if (opt == 'S') { param |= PARAM_S; } else if (opt == 't') { param |= PARAM_t; } else { printf("对不起,目前只支持参数R,S,a,t和l.\n"); exit(0); } }
这些参数是实现定义好的,直接在程序中使用就好了,一般都是将opterr设置为0,使它不打印错误信息。
#include <stdio.h> #include <stdlib.h> #include <getopt.h> int main(int argc, char **argv) { int c; int digit_optind = 0; int this_option_optind = optind ? optind : 1; int option_index = 0; static struct option long_options[] = { {"add", required_argument, 0, 0 }, {"append", no_argument, 0, 0 }, {"delete", required_argument, 0, 0 }, {"verbose", no_argument, 0, 0 }, {"create", required_argument, 0, 'c'}, {"file", required_argument, 0, 0 }, {0, 0, 0, 0 } }; while (1) { c = getopt_long_only(argc, argv, "abc:d:012", long_options, &option_index); if (c == -1) break; switch (c) { case 0: printf("option %s", long_options[option_index].name); if (optarg) printf(" with arg %s", optarg); printf("\n"); break; case '0': case '1': case '2': if (digit_optind != 0 && digit_optind != this_option_optind) printf("digits occur in two different argv-elements.\n"); digit_optind = this_option_optind; printf("option %c\n", c); break; case 'a': printf("option a\n"); break; case 'b': printf("option b\n"); break; case 'c': printf("option c with value '%s'\n", optarg); break; case 'd': printf("option d with value '%s'\n", optarg); break; case '?': break; default: printf("?? getopt returned character code 0%o ??\n", c); } } if (optind < argc) { printf("optind:%d\n",optind); printf("non-option ARGV-elements: "); while (optind < argc) printf("%s ", argv[optind++]); printf("\n"); } exit(EXIT_SUCCESS); }这个例子中首先先看getopt_long()的第三个参数是"abc:d:012",这里的一个冒号代表这个冒号前面这个字符出现时需要有参数,例如这样ls -a5,那个这个5就是一个参数,虽然这个ls没这么用的,这里出现时举个例子,参数会存储在optarg这个变量中,也是事先定义好的,不用自己定义,直接用就可以了。
这个c:代表选项c后面必须跟一个参数。d:同样的意思。
如果是这样---->"c::"那么就是说c可以带参数也可以不带
name长选项的名字
如果参数是可选的是optional_argument或者2
flag如果为NULL,getopt_long()返回该结构val字段中的数值;如果不为NULL,getopt_long()会使得flag所指向的变量中填入val字段中的数值,并且getopt_long()返回0;通常flag设置为NULL,val设置为与该长选项对应的短选项
val一个值,一般写成长选项所对应的短选项
下面来个具体的例子
static struct option long_options[] = { {"add", required_argument, 0, 'a' }, {"delete", required_argument, 0, 'd' }, {"verbose", no_argument, 0, 'v' }, {"create", required_argument, 0, 'c'}, {"file", required_argument, 0, 'f' }, };
还有最后一个参数longindex,这个参数如果传的不是NULL,那么就指向一个具体的int变量,每次调用getopt_long()将会把长选项在longopts中的索引值存入longindex,例如长选项是--delete,那么这个参数就会被设置为1。