getopt_long()使用方法

本文内容大部分翻译自Linux Man Page
用于学习如何解析命令行参数,其中讲解了getopt、getopt_long、getopt_long_only等函数的用法和区别。

对下文中遇到的词汇做一下约定:
比如在终端输入:find /usr -name “*.txt”
选项:-name
参数:/usr、”*.txt”
选项字符:n
选项元素:-name
argv元素:find、/usr、-name、”*.txt”

概要

#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);

描述

getopt()函数用来解析命令行参数。他的参数argcargv分别是main函数传进来的参数个数和参数列表。如果argv中的元素以’-‘或’–’开头,则该元素是一个选项元素。在这个元素’-‘后面的字符是选项字符。如果getopt()被反复调用,若执行成功,则会返回每个argv 中的选项元素的选项字符

optind变量是个全局变量,表示在argv中将要处理的下个元素的下标。一开始初始化这个值为1。如果需要的话,调用者可以重置它为1,比如在同一个程序中想再重新扫描这个argv,或者处理一个新的参数列表。

如果getopt()发现了另一个选项字符,它会返回这个字符,且更新optind变量和nextchar变量以便于下次调用getopt()函数时可以继续处理下一个选项字符或argv元素

如果没有更多的选项字符,getopt()会返回-1。且optind的值设置为argv中第一个非选项的argv元素

optstring是一个包含了合法选项字符的字符串。如果这个字符后面紧跟一个冒号,则说明这个选项需要一个参数,这个参数可以紧跟在这个选项字符的后面,也可以是下一个argv元素,当optstring为”d:”,且命令行中可以传入”-dabc”,则optarg的值为指向”abc”的指针;如果传入的是”-d abc”,则optarg指向下个argv元素,即”abc”元素。两个冒号意味着可以携带一个可选的参数。如果在这个选项字符后紧接着参数(“-dabc”),则optarg会指向这个参数(“abc”),否则optarg会被设置为0。(使用双冒号后,参数必须紧跟在选项字符后面)

默认情况下,getopt()在扫描argv的内容同时会对它进行重新排序,这样可以使得非选项元素都放在后面。还有其他两种模式,当optstring第一个字符为’+’或环境变量POSIXLY_CORRECT被设置,则getopt()在扫描argv时候一遇到非选项元素时候会停止解析处理(getopt()立即返回-1)。如果optstring第一个字符为’-‘,每个非选项元素会被当做字符值为1(即ASCII码为1)的字符选项的参数,也就是说getopt()返回1。这种模式主要是提供给需要关心选项参数的顺序的调用者。如果指定了”–”选项,会终止getopt()的选项处理(不管何种扫描模式),也就是说一律把”–”后面的argv元素当做参数来处理,即使有元素带’-‘。

getopt()函数遇到一个不认识的选项字符(没有在optstring中出现),它会把错误信息打印在stderr中,并且把字符存在optopt中,然后getopt()会返回’?’。如果你不想打印它打印错误信息,可以设置opterr为0。

getopt()函数遇到一个optstirng中没有的字符,或者检测到某个选项缺少参数,则会返回一个’?’,同时设置optopt的值为这个真实遇到的字符。如果optstring的第一个字符(或者在’+’、’-‘后第一个字符)是’:’,则getopt()在遇到缺少参数的选项时会返回’:’来代替’?’。如果检测到一个错误,且optstring的第一个字符不是一个冒号,且opterr的值为非零,getopt()会打印错误信息。

getopt_long()和getopt_long_only()

getopt_long()getopt()除了支持长选项(以”–”开头)外,其他都一样。(如果程序只接受长选项,optstring应该被指定为空字符串(“”))。长选项可以在保证唯一性的情况下可以简写。一个长选项可以这样携带一个参数:–arg=param或者–arg param

longopts是一个指向struct option数组的第一个元素的指针,struct option(在

struct option {
    const char *name;
    int         has_arg;
    int        *flag;
    int         val;
};

结构体option各个字段的意思如下:
name
长选项的名字
has_arg
no_argument(或0):选项不携带参数;required_argument(或1):选项需要参数;optional_argument(或2):选项携带可选参数
flag
指定该长选项的返回值。如果flag是NULL,getopt_long会返回val。(比如,调用者可以设置val为短选项字符)否则,getopt_long会返回0,且flag指向的值设置为val的值,前提是该选项成功找到了。
val
当做返回值,或把值加载进flag所指的内存中。

longopts指向的数组的最后一个元素值都设置为0。

如果longindex不是NULL,它指向getopt_long()获得的长选项在longopts的下标。

getopt_long_only()getopt_long()相似,不同的是getopt_long()会把’-‘和”–”都当做一个长选项处理。而getopt_long_only()会把一个以’-‘开头(不是”–”)的选项当做短选项处理。

返回值

如果成功找到了选项,getopt()会返回选项字符。如果所有的命令行都已经解析完了,getopt()会返回-1。如果getopt()遇到一个optstring没有的选项字符,则会返回’?’。如果遇到一个缺少参数的选项字符,返回值就要取决于optstring的第一个字符了:如果是’:’,则返回’:’,否则返回’?’。

环境

POSIXLY_CORRECT
如果该环境变量被设置,选项处理遇到非选项参数会立马停止(即getopt()等方法会立马返回-1)。

注意

一个程序可以解析多个命令行参数数组,或者可以多次解析同一个命令行参数数组,且如果想在多个解析处理之间使用optstring开头的’+’、’-‘,或改变POSIXLY_CORRECT环境变量的值,必须通过设置optind为0来重新初始getopt(),而不是设置为1。

例子

下面的例子使用getopt()来处理两个选项:-n,不携带任何参数;-t val,它携带一个参数


#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>

int
main(int argc, char *argv[])
{
    int flags, opt;
    int nsecs, tfnd;

    nsecs = 0;
    tfnd = 0;
    flags = 0;
    while ((opt = getopt(argc, argv, "nt:")) != -1) {
        switch (opt) {
            case 'n':
                flags = 1;
                break;
            case 't':
                nsecs = atoi(optarg);
                tfnd = 1;
                break;
            default: /* '?' */
                fprintf(stderr, "Usage: %s [-t nsecs] [-n] name\n", argv[0]);
                exit(EXIT_FAILURE);
        }
    }
    printf("flags=%d; tfnd=%d; optind=%d\n", flags, tfnd, optind);

    if (optind >= argc) {
            fprintf(stderr, "Expected argument after options\n");
            exit(EXIT_FAILURE);
    }

    printf("name argument = %s\n", argv[optind]);

    /* Other code omitted */

    exit(EXIT_SUCCESS);
}

下面的例子使用了getopt_long()的大多数特性。

#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);
}
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: `getopt_long` 是一个 C 语言标准库中的函数,用于解析命令行参数。与 `getopt` 不同的是,`getopt_long` 可以处理长选项(long options),即以两个减号开头的选项。`getopt_long` 的函数原型为: ```c #include <getopt.h> int getopt_long(int argc, char * const argv[], const char *optstring, const struct option *longopts, int *longindex); ``` 其中,`argc` 和 `argv` 分别是命令行参数的个数和数组,`optstring` 是短选项字符串,`longopts` 和 `longindex` 分别是长选项结构体数组和当前处理的长选项的索引。`getopt_long` 函数会依次解析命令行参数,返回当前处理的选项的字符代码,如果已经处理完所有选项,则返回 -1。如果遇到无效选项或缺少参数,会返回 '?',并在 `optopt` 变量中保存无效选项的字符代码或缺少参数的选项的字符代码。`getopt_long` 函数还会修改 `optind` 变量,指示下一个要处理的命令行参数的索引。 ### 回答2: getopt_long是一个函数库,用于处理命令行参数的解析和处理。它是标准C库中getopt函数的扩展版本,提供更加灵活和强大的功能。 getopt_long可以解析命令行参数的各种形式,包括短选项、长选项和参数。它使用了一个结构体数组来定义所有支持的选项和参数,每个选项和参数都有一个相关的处理函数。这个结构体数组的定义可以通过编码方式来指定,也可以通过外部文件来定义。这使得getopt_long可以灵活适应不同的命令行参数需求。 调用getopt_long函数时,它会依次读取命令行参数,解析出对应的选项和参数,并调用相应的处理函数来进行处理。在解析过程中,它可以处理多个选项和参数的组合,并且支持选项和参数的排列顺序任意。 getopt_long还提供了其他辅助函数来帮助处理命令行参数,比如打印错误信息、获取非选项参数等。 总的来说,getopt_long是一个强大的函数库,可以方便地处理各种形式的命令行参数,并提供了多种功能来满足不同的应用需求。它在编程中的使用可以帮助程序员更加高效地处理命令行参数,提高代码的可维护性和可扩展性。 ### 回答3: getopt_long是一个在C语言中用来解析命令行参数的函数。它是标准库中getopt函数的一个扩展,可以处理更复杂和更灵活的命令行选项。 getopt_long函数包含在头文件<getopt.h>中,使用时需要传入一些参数。其中,长选项是以结构体数组的形式传入函数的,每个结构体包含了选项名、选项标志以及选项值等信息。通过判断输入的命令行参数是否匹配传入的长选项,函数可以进行相应的处理。 getopt_long函数返回一个整型值,当解析完所有选项时返回-1,否则循环解析每个选项,并返回选项的字符值,或者根据参数optstring中的":"和"?"进行错误处理。 getopt_long函数可以处理带有参数的长选项,例如"--output=file",我们可以通过optarg变量获取选项参数的值。另外,它还可以处理短选项,如"-o",并且可以支持多个选项合并在一起,如"-ov"代表同时设置-o和-v两个选项。 通过使用getopt_long函数,我们可以方便而灵活地解析命令行参数,实现不同的功能。它可以在命令行中设置各种选项,例如调试模式、输出文件名、日志级别等等。同时,getopt_long使用方法也相对简单,只需要了解相关参数和函数的用法,就可以轻松地处理命令行参数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值