c/c++中参数处理get_opt()/get_opt_long

背景

  在用c写测试工具的时候也希望看到跟linux中常用工具那样的详细的参数说明。这时我们就需要用到c中常用的参数处理函数get_opt(),get_long().这两个函数在头文件#include<getopt.h>中,使用时使自己的c文件包含这个头文件就可以了,接下来详细介绍一下这两个函数的使用方法。

1. 短参数处理函数get_opt()

  • 使用场景:
    getopt是用来解析命令行选项参数的,但是只能解析短选项: -d 100,不能解析长选项:--prefix

  • 函数原型

int getopt(int argc, char * const argv[], const char *optstring);
    
-- optstring: 选项字符串,告知 getopt()可以处理哪个选项以及哪个选项需要参数
  • 重点参数讲解 optstring
char *optstring = “ab:c::”;
单个字符a         表示选项a没有参数            格式:-a即可,不加参数
单字符加冒号b:     表示选项b有且必须加参数      格式:-b 100或-b100,但-b=100错
单字符加2冒号c::   表示选项c可以有,也可以无     格式:-c200,其它格式错误

上面这个 optstring 在传入之后,getopt 函数将依次检查命令行是否指定了 -a, -b, -c(这需要多次调用 getopt 函数,直到其返回-1),
当检查到上面某一个参数被指定时,函数会返回被指定的参数名称(即该字母),然后我们可以用下面的变量来获取我们所期待的值:
optarg —— 指向当前选项参数(如果有)的指针,本身是指针,如果value是一个字符,那么可以取optarg[0]。
optind —— 再次调用 getopt() 时的下一个 argv指针的索引。
optopt —— 最后一个未知选项。
opterr ­—— 如果不希望getopt()打印出错信息,则只要将全域变量opterr设为0即可。
  • 返回值
    如果选项成功找到,返回选项字母;如果所有命令行选项都解析完毕,返回 -1;如果遇到选项字符不在 optstring 中,返回字符 '?';如果遇到丢失参数,那么返回值依赖于 optstring 中第一个字符,如果第一个字符是 ':' 则返回':',否则返回'?'并提示出错误信息

  • 例程:

#include<stdio.h>
#include<unistd.h>
#include<getopt.h>
int main(intargc, char *argv[])
{
    int opt;
    char *string = "a::b:c:d";
    while ((opt = getopt(argc, argv, string))!= -1)
    {  
        printf("opt = %c\t\t", opt);
        printf("optarg = %s\t\t",optarg);
        printf("optind = %d\t\t",optind);
        printf("argv[optind] = %s\n",argv[optind]);
    }  
}

编译后可以用下面任何一种格式调用:
./opt -a100 -b 200 -c 300 -d
./opt -a100 -b200 -c300 -d 
./opt -a -b 200 -c 300 -d 

2. 长参数处理函数get_opt()

  • 使用场景:
    getopt_long 函数包含了 getopt 函数的功能,并且还可以指定"长参数”(--ip 127.0.0.1 , --help之类的)

  • 函数原型

int getopt_long(int argc, char * const argv[], const char *optstring,
                         const struct option *longopts, int *longindex);

可以看到比get_opt()多了两个参数 longopts, logindex.
  • 重点参数讲解
- longopts    指明了长参数的名称和属性,可以看到它是一个结构体指针,我们通常传一个结构体数组进去,每个元素代表一个参数,每个参数都是由下面的结构组成。
struct option {
  const char  *name;       /* 参数名称 */
  int          has_arg;    /* 指明是否带有参数 */
  int          *flag;      /* flag=NULL时,返回value;不为空时,*flag=val,返回0 */
  int          val;        /* 用于指定函数找到选项的返回值(长选项的缩写)或flag非空时指定*flag的值 */
};

- longindex   如果longindex非空,它指向的变量将记录当前找到参数符合longopts里的第几个元素的描述,即是longopts的下标值
  • 返回值
    对于短选项,返回值同getopt函数;对于长选项,如果flag是NULL,返回val,否则返回0;对于错误情况返回值同getopt函数

  • 例程

int main(intargc, char *argv[])
{
    int opt;
    int digit_optind = 0;
    int option_index = 0;
    char *string = "a::b:c:d";
    static struct option long_options[] =
    {  
        {"reqarg", required_argument,NULL, 'r'},
        {"optarg", optional_argument,NULL, 'o'},
        {"noarg",  no_argument,         NULL,'n'},
        {NULL,     0,                      NULL, 0},
    }; 
    while((opt =getopt_long_only(argc,argv,string,long_options,&option_index))!= -1)
    {  
        printf("opt = %c\t\t", opt);
        printf("optarg = %s\t\t",optarg);
        printf("optind = %d\t\t",optind);
        printf("argv[optind] =%s\t\t", argv[optind]);
        printf("option_index = %d\n",option_index);
    }  
}

编译执行结果:
./long --reqarg 100 --optarg=200 --noarg
opt = r optarg =100     optind = 3   argv[optind] = --optarg=200  option_index = 0
opt = o optarg =200     optind = 4   argv[optind] = --noarg        option_index = 1
opt = n optarg =(null) optind = 5    argv[optind] =(null)          option_index = 2
  • 例程2
#include <unistd.h>
#include<getopt.h>

void usage(void)
{
    fprintf(stdout, "Usage: %s",
        "consistency_check <-t type> <--ip addr> <-f file>\n\n\
        -t type: specify s/c of the routine, the server start write first and \n\
                 and the client will notify server stop write, then write the \n\
                 same file and do read and check.\n\n\
        -f file: the file name we will do IO.\n\n\
        --ip addr: the ip of server.\n\n");
}
static struct option long_options[] = {
    {"ip", required_argument, NULL, 'i'},
};

int main ()
{
  string name;
  char *ip_addr;
  char type;
  int opt;

  while((opt =getopt_long(argc,argv,"t:f:",long_options, NULL))!= -1)
    {
       switch(opt) {
        case 't':
            type = optarg[0];
            break;
        case 'f':
            name = optarg;
            break;
        case 'i’: // ip’s short char
            ip_addr = optarg;
            break;
        defaul:
            usage();
       }
    }

  cout << "+----------------------------------------------------------------------------+" << endl;
  cout << "|Type: " << type << "  IP: " << ip_addr << "  file: " << name << endl;;
  cout << "+----------------------------------------------------------------------------+" << endl;
}

参考

https://www.cnblogs.com/chenliyang/p/6633739.html

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335

推荐阅读更多精彩内容