免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 9752 | 回复: 5
打印 上一主题 下一主题

getopt和getopt_long函数使用介绍 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-11-20 20:03 |只看该作者 |倒序浏览
Linux选项解释-getopt和getopt_long函数
一、命令行简介

解释分析命令行通常是所以程序的第一个任务,C语言通过argc和argv参数来访问它的命令行参数。

最简单的命令行处理技术可以通过if判断来表示,如下例:

if(argc>1 &&argv[1][0] ==  ‘ - ‘  &&argv[1][1] ==  ‘ h ’ )  //判断命令行参数是否为-n

{

     do _ some thing();

}

这样处理简单有序的命令行还可以,对于复杂的命令行处理显得有心无力,于是GNU提供两个函数专门用来处理命令行参数:getopt和getopt_long。

二、getopt函数

getopt()函数声明如下:

C代码
#include <unistd.h>   
  
Int getopt(int argc, char *const argv[], const char *optstring);   
  
extern char *optarg;   
  
extern int optind, opterr, optopt;  

#include <unistd.h>

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

extern char *optarg;

extern int optind, opterr, optopt;
  


说明:函数中的argc和argv通常直接从main()到两个参数传递而来。optsting是选项参数组成的字符串,如果该字符串里任一字母后有冒号,那么这个选项就要求有参数,optarg就是选项参数。optind是当前索引,optopt用于当发现无效选项字符的时候,getopt函数或者返回 “?”或者返回“:”字符,并且optopt包含了所发现的无效选项字符。

如果optstring参数的第一个字符是冒号,那么getopt会根据错误情况返回不同的字符,当错误是无效选项,getopt返回“?”,当错误是缺少选项参数,getopt返回“:”。

注:GNU getopt()第三个特点是optstring中的选项字符后面接两个冒号,就允许该选项有可选的选项参数。在选项参数不存在的情况下,GNU getopt()返回选项字符并将optarg设置为NULL。

例子:

C代码
#include <stdio.h>   
  
#include <unistd.h>   
  
#include <getopt.h>   
  
char *para = ":ab:c";   
  
int main(int argc, char *argv[])   
  
{   
  
     int oc = -1;   
  
     char *b_input = NULL;   
  
     while((oc = getopt(argc, argv, para)) != -1)   
  
     {   
  
         switch(oc)   
  
         {   
  
          case 'a':   
  
              printf("input para is a\n";   
  
              break;   
  
          case 'b':   
  
              b_input = optarg;   
  
              printf("input para is b,and optarg is %s\n", b_input);   
  
              break;   
  
          case 'c':   
  
              printf("input para is c\n";   
  
              break;   
  
          case ':':   
  
              printf("option %c requires an argument\n",optopt);   
  
              break;   
  
          case '?':   
  
          default:   
  
              printf("option %c is invalid:ignored\n",optopt);   
  
             break;   
  
         }   
  
     }   
  
     return 0;   
  
}  

#include <stdio.h>

#include <unistd.h>

#include <getopt.h>

char *para = ":ab:c";

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

{

     int oc = -1;

     char *b_input = NULL;

     while((oc = getopt(argc, argv, para)) != -1)

     {

         switch(oc)

         {

          case 'a':

              printf("input para is a\n";

              break;

          case 'b':

              b_input = optarg;

              printf("input para is b,and optarg is %s\n", b_input);

              break;

          case 'c':

              printf("input para is c\n";

              break;

          case ':':

              printf("option %c requires an argument\n",optopt);

              break;

          case '?':

          default:

              printf("option %c is invalid:ignored\n",optopt);

             break;

         }

     }

     return 0;

}
  


编译:

[root@heguangwu projects]# gcc -o getopt_ex getopt_ex.c

运行:

[root@heguangwu projects]# ./getopt_ex -a

input para is a

[root@heguangwu projects]# ./getopt_ex -a -b

input para is a

option b requires an argument

[root@heguangwu projects]# ./getopt_ex -d

option d is invalid:ignored



三、getopt_long函数

getopt_long用来处理长选项,使用 man 3 getopt_long ,得到其声明如下:

C代码
#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);  

#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相同,下一个参数是指向数组的指针,这个数组是option结构数组,option结构称为长选项表,其声明如下:

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

struct option
{

    const char *name;

    int  has_arg;

    int  *flag;

    int  val;

};
  


结构中的元素解释如下:

const char *name :选项名,前面没有短横线

int has_arg:描述长选项是否有参数,其值见下表

符号常量
数值
含义

no_argument

required_argument

optional_argument
0

1

2
选项没有参数

选项需要参数

选项参数是可选的


int *flag:

如果该指针为NULL,那么getopt_long返回val字段的值;

如果该指针不为NULL,那么会使得它所指向的结构填入val字段的值,同时getopt_long返回0

int val:

如果flag是NULL,那么val通常是个字符常量,如果短选项和长选项一致,那么该字符就应该与optstring中出现的这个选项的参数相同;





C代码
#include <stdio.h>   
  
#include <unistd.h>   
  
#include <getopt.h>   
  
char *para = ":ab:cf:v";   
  
int do_all = 0;   
  
int do_help = 0;   
  
int do_version = 0;   
  
char *file = NULL;   
  
struct option longopt[] =   
  
{   
  
     {"all", no_argument, &do_all, 1},   
  
     {"file", required_argument, NULL, 'f'},   
  
     {"help", no_argument, &do_help, 1},   
  
     {"version", no_argument, &do_version, 1},   
  
     {"bob", required_argument, NULL, 'b'},   
  
     {0, 0, 0, 0},   
  
};   
  
int main(int argc, char *argv[])   
  
{   
  
    int oc = -1;   
  
    char *b_input = NULL;   
  
    while((oc = getopt_long(argc, argv, para, longopt, NULL)) != -1)   
  
    {   
  
         switch(oc)   
  
         {   
  
         case 'a':   
  
               printf("input para is a\n";   
  
              break;   
  
         case 'b':   
  
              b_input = optarg;   
  
              printf("input para is b,and optarg is %s\n", b_input);   
  
             break;   
  
        case 'c':   
  
             printf("input para is c\n";   
  
            break;   
  
        case 'v':   
  
            printf("input para is v\n";   
  
            break;   
  
        case 'f':   
  
            printf("input para is f\n";   
  
            file = "hello world";   
  
            break;   
  
        case 0:   
  
           break;   
  
        case ':':   
  
             printf("option %c requires an argument\n",optopt);   
  
             break;   
  
         case '?':   
  
         default:   
  
            printf("option %c is invalid:ignored\n",optopt);   
  
            break;   
  
         }   
  
     }   
  
     printf("do_all is %d\n",do_all);   
  
     printf("do_help is %d\n",do_help);   
  
     printf("do_version is %d\n",do_version);   
  
     printf("do_file is %s\n",file);   
  
     printf("bob is %s\n", b_input);   
  
     return 0;   
  
}  

#include <stdio.h>

#include <unistd.h>

#include <getopt.h>

char *para = ":ab:cf:v";

int do_all = 0;

int do_help = 0;

int do_version = 0;

char *file = NULL;

struct option longopt[] =

{

     {"all", no_argument, &do_all, 1},

     {"file", required_argument, NULL, 'f'},

     {"help", no_argument, &do_help, 1},

     {"version", no_argument, &do_version, 1},

     {"bob", required_argument, NULL, 'b'},

     {0, 0, 0, 0},

};

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

{

    int oc = -1;

    char *b_input = NULL;

    while((oc = getopt_long(argc, argv, para, longopt, NULL)) != -1)

    {

         switch(oc)

         {

         case 'a':

               printf("input para is a\n";

              break;

         case 'b':

              b_input = optarg;

              printf("input para is b,and optarg is %s\n", b_input);

             break;

        case 'c':

             printf("input para is c\n";

            break;

        case 'v':

            printf("input para is v\n");

            break;

        case 'f':

            printf("input para is f\n");

            file = "hello world";

            break;

        case 0:

           break;

        case ':':

             printf("option %c requires an argument\n",optopt);

             break;

         case '?':

         default:

            printf("option %c is invalid:ignored\n",optopt);

            break;

         }

     }

     printf("do_all is %d\n",do_all);

     printf("do_help is %d\n",do_help);

     printf("do_version is %d\n",do_version);

     printf("do_file is %s\n",file);

     printf("bob is %s\n", b_input);

     return 0;

}
  




执行的结果: 只显示关键结果

[root@heguangwu projects]# ./opt_ex2 -a

input para is a



[root@heguangwu projects]# ./opt_ex2 --all

do_all is 1



[root@heguangwu projects]# ./opt_ex2 -f h

input para is f

do_file is hello world



[root@heguangwu projects]# ./opt_ex2 --bob aa

input para is b,and optarg is aa

bob is aa



[root@heguangwu projects]# ./opt_ex2 -b aa

       input para is b,and optarg is aa

论坛徽章:
0
2 [报告]
发表于 2010-11-20 21:50 |只看该作者
内核源码版块怎么出现这个东西...

论坛徽章:
0
3 [报告]
发表于 2010-11-21 08:42 |只看该作者
哦 我只想说明一下 netfilter防火墙中,能用到这个函数,实现用户输入命令的解析
如果不是这 呵呵 那就发错了

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
4 [报告]
发表于 2010-11-21 10:54 |只看该作者
哦 我只想说明一下 netfilter防火墙中,能用到这个函数,实现用户输入命令的解析
如果不是这 呵呵 那就发错 ...
wuwenhua 发表于 2010-11-21 08:42


LZ 说的是 iptables 命令行吧。

如果能偶结合 iptables 来分析就更好了。

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
5 [报告]
发表于 2010-11-21 11:01 |只看该作者
内核源码版块怎么出现这个东西...

内核版也欢迎讨论一些和内核有关系比较直接的应用代码的交流。比如 iptables 之类的源码等等。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
6 [报告]
发表于 2010-11-21 19:50 |只看该作者
⊙﹏⊙b汗,我还以为是shell脚本中的那个getopts
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP