跳转至

Getopt

1 Synopsis

getopt 是一个用于解析命令行参数的 C 语言函数,getopt_longgetopt 的增强版本,它支持长选项

2 Description

getopt()

C
1
2
3
4
5
6
7
#include <unistd.h>

int getopt(int argc, char * const argv[],
          const char *optstring);

extern char *optarg;
extern int optind, opterr, optopt;
  • argc:对应 main()argc
  • argv:对应 main()argv
  • optstring:定义了合法的选项及其格式
  • 单个字符表示简单选项(如 a 对应 -a
  • 字符后接冒号 : 表示该选项需要参数(如 f: 对应 -f file
  • 字符后接两个冒号 :: 表示该选项的参数是可选的(如 f:: 对应 -f[file]

全局参数解析:

  • optarg:用于存储当前选项的参数

如果没有参数,则 optarg 被设为 0

  • optind:下一个要处理的参数索引

  • opterr:是否显示错误信息

默认情况下,getopt() 遇到无效选项或未知选项默认会打印错误,未知/无效选项存放在 optopt,并返回 ?

opterr 被设为 0,那么 getopt() 遇到无效选项或未知选项不会打印错误信息,可通过检查函数返回值是否

'?' 来判断是否出错

  • optopt:存放无法识别的选项字符

返回值:

返回值 含义 条件
选项字符 成功识别了一个选项 选项在 optstring 中定义
-1 选项处理完毕 已到达参数列表末尾或遇到非选项参数
'?' 未知选项 选项不在 optstring 中定义
'?' 缺少必需参数 选项需要参数但未提供(当 optstring 不以 ':' 开头时)
':' 缺少必需参数 选项需要参数但未提供(当 optstring':' 开头时)

getopt_long()

C
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
#include <getopt.h>

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

struct option {
   const char *name;
   int         has_arg;
   int        *flag;
   int         val;
};
  • argc:对应 main()argc
  • argv:对应 main()argv
  • optstring:定义了合法的选项及其格式
  • 单个字符表示简单选项(如 a 对应 -a
  • 字符后接冒号 : 表示该选项需要参数(如 f: 对应 -f file
  • 字符后接两个冒号 :: 表示该选项的参数是可选的(如 f:: 对应 -f[file]
  • longopts:指向 struct option 数组的指针,定义了长选项的格式
  • longindex:用于存储当前匹配的长选项在 longopts 数组中的索引,如果不需要此信息,可以将其设置为 NULL

struct option 解析:

C
1
2
3
4
5
6
struct option {
   const char *name;
   int         has_arg;
   int        *flag;
   int         val;
};
  • name:长选项的名称
  • has_arg:参数要求
  • no_argument 或 0:选项不带参数(如 --help
  • required_argument 或 1:选项需要参数(如 --output file.txt
  • optional_argument 或 2:选项参数可选(如 --prefix[=path]
  • flag:定义返回值方式
  • flag == NULLgetopt_long() 返回 val 中定义的值
  • flag != NULLgetopt_long() 返回 0,并将 flag 指向 val
  • val:定义返回值

返回值:

返回值 含义 条件
短选项字符 成功识别了一个短选项 选项在 optstring 中定义
val 成功识别了一个长选项,且 flagNULL 选项在 longopts 数组中定义
0 成功识别了一个长选项,且 flag 不为 NULL 选项在 longopts 数组中定义
-1 选项处理完毕 已到达参数列表末尾或遇到非选项参数
'?' 未知选项 选项不在 optstringlongopts 中定义
'?' 缺少必需参数 选项需要参数但未提供(当 optstring 不以 ':' 开头时)
':' 缺少必需参数 选项需要参数但未提供(当 optstring':' 开头时)

3 Example

getopt()

C
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
  int opt;
  while ((opt = getopt(argc, argv, "hf:")) != -1) {
     switch (opt) {
         case 'h': /* Todo() */ break;
         case 'f': /* Todo() */ break;
         default:  /* Erro() */ break;
        }
    }

    return 0;
}

getopt_long()

C
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <getopt.h>

int main(int argc, char *argv[]) {

  struct option long_options[] = {
    { "help", no_argument      , 0, 'h' },
    { "elf" , required_argument, 0, 'e' },
    { 0     , 0                , 0, 0   }
  };

  const char *optstring = "he:";

  int opt;
  int opt_idx = 0;

  while ((opt = getopt_long(argc, argv, optstring, long_options, &opt_idx)) != -1) {
    switch (opt) {
      case 'h':
        printf("The program apply to parse the elf file.\n");
        printf("Usage: -e [elf file]\n");
        break;
      case 'e':
        const char* file_name = optarg;
        read_elf_symboltable(file_name);
        break;
      default:
        break;
    }
  }

  return 0;
}