C++ getopt

本文介绍了C++中用于处理命令行选项参数的函数getopt()、getopt_long()和getopt_long_only()。getopt()用于处理短选项,getopt_long()增加了长选项的支持,而getopt_long_only()允许长选项以短选项形式出现。文章详细阐述了这些函数的工作原理,包括optstring、optind、optarg等关键参数的使用,以及它们在处理非法选项、缺失参数和结束标志时的行为。
摘要由CSDN通过智能技术生成

本文讲解如何处理命令行传入的选项和参数

比如我们执行如下指令会输出file文件的前10行:

head file // 默认输出file的前10行

如果我们想要输出文件的前50行,就可以加选项"-n"和参数50

head -n 50 file

通过传入-n 50, head程序就知道我们想要得到是前50行。



在C/C++中,我们通过getopt()、getopt_long()以及getopt_long_only()函数来处理这些传入的选项参数。

getopt()

#include <unistd.h>

extern char* optarg
extern int optind
extern int opterr
extern int optopt 

int getopt(int argc, char* const argv[], const char* optstring)
                |                  |
                |                  |getopt()中的argc, argv就是main()中的argc, argv
                |                  |
int main(int argc, char* const argv[])

argc是传入的所有参数的数量
argv是传入的参数array

比如我们有一个编译为main的程序,当执行如下指令:

./main -t 100 -c 200 file

argc = 6 (包括./main, -t, 100, -c, 200, file)
argv就是“-t 100 -c 200 file” 

除此之外还需要了解几个概念:

  • option element
    以 ‘-’ 开始的选项
    比如-t, -c就是option element,而100, 200, file不是(是’-‘而不是"-“或者”–")
    t和c又称为option character
    如果读取到了’-’,后面却没有对应的option character,getopt()会返回-1

  • optind
    这个变量指向在argv中要读取的下一个character的位置
    比如getopt()读取到了-t,它会将optind更新指向下一个可以读取到option element的地方(在这里就是-s)
    这样,下次再次调用optget()的时候,getopt()就知道应该从哪里继续读取了
    optind最终会停在第一个不是option element的地方(比如这里就是file)

  • optarg
    指向参数的指针
    比如getopt()读取到了-t,那么optarg就会指向后面的参数’100’开始的位置

  • optstring
    optstring代表合法的option character。
    假如我们定义optstring = “a: b :c ::”,就代表,我们输入的选项可以有-a -b和-c
    optstringt里面的冒号":“代表这个选项后面需要一个参数,那么当读取了-t后,optarg会自动指向参数开始的地方
    两个冒号”::“代表选项可以有参数,也可以没有参数。
    如果optstring以‘+’开头,如”+a: b: c::",那么一旦getopt()读取到一个非option的选项,就会立刻停止,不会继续处理argv了
    如果optstring以’-'开头,如"-a: b: c::",那么即使读到非option选项,getopt()还是会继续处理argv,只是把这些非option选项当做一个特殊的option选项的参数。

  • optopt
    假如getopt()读取到了一个不在optstring中的character,也就是读取到了一个不合法的option,它会输出error信息,并且将这个不合法的option character存到optopt中,然后返回一个’?’

return value

  1. 遇到的option是合法的:返回这个option character
  2. 遇到的option不合法:返回’?’
  3. 遇到的option缺参数:可能返回’:‘或者’?’ (取决于optstring的第一个character)
  4. 所有options都处理完毕:返回-1

getopt_long()

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

getopt_long()和getopt()很像,不同的是它可以接受long option (’–'开始的option)。

./main -n 100     // getopt()只能处理'-'开始的短选项
./main --opt 100  // getopt_long()可以处理'--'开始的长选项
  • optstring定义了合法的option character,意思就是,不包含long option
    所以如果只有但是character的options,那么optstring应该设置为optstring = “” (不要设置为NULL)

-longopts
假设有多个long options,这些long options会被存在一个数组里
longopts就指向这个数组。

#include <getopt.h>

struct option{
	const char* name;  // long option的名字
	int has_arg; // has_arg = 0 : 这个long option不需要参数
	             // has_arg = 1 : 这个long option需要参数
	             // has_arg = 2 : 这个long option参数可有可无
	int *flag;   // flag = NULL: getopt_long() returns val
	             // flag != NULL : getopt_long() returns 0
	int val;    
}

-longindex
如果longindex不为NULL的话,假设有一个数组存储了多个long options
当前long option是数组中的第3个options,那么longindex就指向这个3

return value:

  1. 处理成功short option:返回option character
  2. flag = NULL : 返回val
  3. flag != NULL: 返回0
  4. 遇到的option不合法:返回’?’
  5. 遇到的option缺参数:可能返回’:‘或者’?’ (取决于optstring的第一个character)
  6. 所有options都处理完毕:返回-1

getopt_long_only()

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

在getopt_long_only()中,long option可以以’-‘或者’–‘开始。如果option以’-'开始却不是一个long option,那么会被转为一个short option来处理。

return value:

  1. 处理成功short option:返回option character
  2. flag = NULL : 返回val
  3. flag != NULL: 返回0
  4. 遇到的option不合法:返回’?’
  5. 遇到的option缺参数:可能返回’:‘或者’?’ (取决于optstring的第一个character)
  6. 所有options都处理完毕:返回-1

example

#include <stdio.h>     /* for printf */
#include <stdlib.h>    /* for exit */
#include <getopt.h>

int
main(int argc, char **argv)
{
    int c;
    int digit_optind = 0;

   while (1) {
        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 }
        };

       c = getopt_long(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("non-option ARGV-elements: ");
        while (optind < argc)
            printf("%s ", argv[optind++]);
        printf("\n");
    }

   exit(EXIT_SUCCESS);
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值