GNU 长选项命令解析--getopt_long()

Linux系统下,需要大量的命令行选项,如果自己手动解析他们的话实在是有违软件复用的思想,不过还好,GNU C library留给我们一个解析命令行的接口(X/Open规范),好好使用它可以使你的程序改观不少。 使用getopt_long()需要引入头文件 #include 现在我们使用一个例子来说明它的使用。 一个应用程序需要如下的短选项和长选项。 短选项 长选项 作用 -h --help 输出程序命令行参数说明然后退出 -c filename --cat filename 给定显示文件名 -v --version 显示程序当前版本后退出 为了使用getopt_long函数,我们需要先确定两个结构: 1.一个字符串,包括所需要的短选项字符,如果选项后有参数,字符后加一个":"符号。本例中,这个字符串应该为"hc:v"。(因为-o后面有参数filename,所以字符后面要加":") 2.一个包含长选项字符串的结构体数组,每一个结构体包含4个域,第一个域为长选项字符串,第二个域是一个标识,只能为0或1,分别代表没有、有。第三个域永远为NULL。第四个域为对应的短选项字符串。结构体数组的最后一个元素全部为NULL和0,标识结束。在本例中,它应该像一下的样子: const struct option long_options[] = { { "help", 0, NULL, 'h' }, { "cat", 1, NULL, 'c' }, { "version", 0, NULL, 'v' }, { NULL, 0, NULL, 0} }; 调用时需要把main的两个参数argc和argv以及上述两个数据结构传给getopt_long。 每次调用getopt_long,它会解析一个符号,返回相应的短选项字符,如果解析完毕返回-1。所以需要使用一个循环来处理所有的参数,而相应的循环里会使用switch语句进行选择。如果getopt_long遇到一个无效的选项字符,它会打印一个错误消息并且返回'?',很多程序会打印出帮助信息并且中止运行;当getopt_long解析到一个长选项并且发现后面没有参数则返回':',表示缺乏参数。当处理一个参数时,全局变量optarg指向下一个要处理的变量。当getopt_long处理完所有的选项后,全局变量optind指向第一个未知的选项索引。 这一个例子代码为下: /*----------------------------------------------------------------------- 文件名:getopt_long.c 编译环境: Ubuntu6.10, gcc 功能: 对可执行文件的参数的长短选项的解析. _____________________________________________*/ #include #include #include #include #define FLAG_VERSION (1<<0) #define FLAG_HELP (1<<1) #define FLAG_LS (1<<2) #define FLAG_CAT (1<<4) #define VERSION "1.01" struct opt { unsigned int flags; char *filename; }; struct opt opt; /* Return -1 on error, 0 on success */ int parse_cmd_line(int argc, char *const argv[]) { int option; const char *optstring = "hlc:v?"; struct option longopts[] = { {"cat", required_argument, NULL, 'c'}, {"ls", no_argument, NULL, 'l'}, {"help", no_argument, NULL, 'h'}, {"version", no_argument, NULL, 'v'}, {0, 0, 0, 0} }; while ((option = getopt_long(argc, argv, optstring, longopts, NULL)) != -1) switch (option) { case 'c': opt.flags |= FLAG_CAT; opt.filename = optarg; break; case 'h': opt.flags |= FLAG_HELP; break; case 'l': opt.flags |= FLAG_LS; break; case 'v': opt.flags |= FLAG_VERSION; break; case '?': opt.flags |= FLAG_HELP; return -1; } if ((opt.flags & FLAG_CAT) && (opt.filename == NULL)) { return -1; } return 0; } void print_help(void) { static const char *help = "Usage: getopt_long [OPTIONS]/n" "Options are:/n" " -c, --cat Get one file content (Format: getopt_long -c /etc/password)/n" " -l, --ls Get current directory's file and directory/n" " -h, --help Display this help text and exit/n" " -v, --version Display the version and exit/n"; printf("%s", help); } int main(int argc, char **argv) { char par[128] = ""; if (argc < 2) { print_help(); exit(0); } opt.flags = 0; if (parse_cmd_line(argc, argv) < 0) { // parse command line. exit(-1); } if (opt.flags & FLAG_HELP) { // get 'help' . print_help(); exit(0); } if (opt.flags & FLAG_VERSION) { // get version of soft. printf("Soft Version:%s/n", VERSION); exit(0); } if (opt.flags & FLAG_CAT) { // 'cat' a file sprintf(par, "%s%c%s", "cat", ' ', opt.filename); system(par); exit(0); } if (opt.flags & FLAG_LS) { // 'ls' current directory system("ls -l"); exit(0); } return 0; } 编译: gcc -o getopt_long getopt_long.c --------------------------------------------------------------------------- 运行: ./getopt_long -c /etc/passwd 结果: root:x:0:0:root:/root:/bin/bash setup:x:0:0:root:/:/usr/sbin/setup nobody:x:99:99:Nobody:/: squid:x:100:100:Squid user:/: snort:x:101:101:Snort user:/: sshd:x:102:102:SSH user:/: ntpd:x:103:103:NTPD user:/: imspector:x:104:104:IMSpector user:/: clam:x:105:105:Clam user:/: sip:x:106:106:SIP user:/: mysql:x:107:107:MySQL user:/: --------------------------------------------------------------------------- 运行: ./getopt_long -v 结果: Soft Version:1.01 --------------------------------------------------------------------------- 如果要运行长选项也是一样的结果,如: ./getopt_long --cat /etc/passwd ./getopt_long --ls ./getopt_long --version

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值