注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

旷世的忧伤

不与夏虫语寒,不与曲人语道,因为生命缺乏言说的条件......

 
 
 

日志

 
 

C语言解析命令行参数  

2015-04-12 20:42:54|  分类: C语言 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
短参数处理 getopt
函数声明:

#include <unistd.h>

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

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

参数说明:
argc和argv参数通常直接从main()的参数直接传递而来
optstring是选项字母组成的字串。如果该字串里的任一字符后面有冒号,那么这个选项就要求有选项参数

optarg是当前选项参数字串(如果有)。
optind是argv的当前索引值。当getopt()在while循环中使用时,循环结束后,剩下的字串视为操作数,在argv[optind]至argv[argc-1]中可以找到。
opterr是这个变量非零时,getopt()函数为“无效选项”和“缺少参数选项,并输出其错误信息。
optopt是当发现无效选项字符之时,getopt()函数或返回'?'字符,或返回':'字符,并且optopt包含了所发现的无效选项字符。

全局变量说明:
当给定getopt()命令参数的数量 (argc)、指向这些参数的数组 (argv) 和选项字串 (optstring) 后,getopt() 将返回第一个选项,并设置一些全局变量。使用相同的参数再次调用该函数时,它将返回下一个选项,并设置相应的全局变量。如果不再有可识别的选项,将返回 -1,此任务就完成了。

不正确的调用程序在所难免,这种错误要么是命令行选项无效,要么是缺少选项参数。正常情况下,getopt()会为这两种情况输出自己的出错信息,并且返回'?'。

例:

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

    while((optionchar = getopt(argc, argv, "nah:")) != -1)
    {
       switch(optionchar)
       {
          case 'n':
             printf("My name is Lyong.\n");
             break;
          case 'a':
             printf("My age is 24.\n");
             break;
          case 'h':
             printf("my hometown is %s\n", optarg);
             break;
          case '?':
             printf("arguments error!\n");
             break;
       }
    }

    return 0;
}

运行结果:

huoty$[getopt] -> ./a.out -nah beijing
My name is Lyong.
My age is 24.
my hometown is beijing

如果不希望输出任何错误信息,或更希望输出自定义的错误信息。可以采用以下两种方法来更改getopt()函数的出错信息输出行为:
1. 在调用getopt()之前,将opterr设置为0,这样就可以在getopt()函数发现错误的时候强制它不输出任何消息。
2. 如果optstring参数的第一个字符是冒号,那么getopt()函数就会保持沉默,并根据错误情况返回不同字符,如下:
“无效选项” —— getopt()返回'?',并且optopt包含了无效选项字符(这是正常的行为)。
“缺少选项参数” —— getopt()返回':',如果optstring的第一个字符不是冒号,那么getopt()返回'?',这会使得这种情况不能与无效选项的情况区分开。

例:

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

    if( argc == 1 )
    {
        printf("没有任何选项\n");
        return 1;
    }

    while((optionchar = getopt(argc, argv, ":nah:")) != -1)
    {
        switch(optionchar)
        {
            case 'n':
                printf("My name is Lyong.\n");
                break;
            case 'a':
                printf("My age is 24.\n");
                break;
            case 'h':
                printf("my hometown is %s\n", optarg);
                break;
            case '?':
                invalidchar = optopt;
                printf("无效的选项字符 \' %c \'!\n", invalidchar);
                break;
            case ':':
                printf("缺少选项参数!\n");
                break;
        }
    }

    return 0;
}

运行结果:

huoty$[getopt] -> ./a.out 
没有任何选项
huoty$[getopt] -> ./a.out -nah beijing
My name is Lyong.
My age is 24.
my hometown is beijing
huoty$[getopt] -> ./a.out -qwer
无效的选项字符 ' q '!
无效的选项字符 ' w '!
无效的选项字符 ' e '!
无效的选项字符 ' r '!
huoty$[getopt] -> ./a.out -h
缺少选项参数!



长参数处理 getopt_long_only和getopt_long(两者用法差不多)
函数声明:

#include <getopt.h> //getopt_long()头文件位置    
int getopt_long (int ___argc, char *const *___argv,    
            const char *__shortopts,    
                const struct option *__longopts, int *__longind);    
int getopt_long_only (int ___argc, char *const *___argv,    
                 const char *__shortopts,    
                     const struct option *__longopts, int *__longind);   

参数说明:
argc argv :直接从main函数传递而来
shortopts:短选项字符串。如”n:v",这里需要指出的是,短选项字符串不需要‘-’,而且但选项需要传递参数时,在短选项后面加上“:”。
longopts:struct option 数组,用于存放长选项参数。
longind:用于返回长选项在longopts结构体数组中的索引值,用于调试。一般置为NULL

struct option结构原型如下:

struct option    
{    
  const char *name;//长选项名    
  int has_arg;//是否需要参数    
  int *flag;    
  int val;    
};    

name:长选项名字 
has_arg:是否需要参数。值有三种情况:

# define no_argument        0    //不需要参数    
# define required_argument  1    //必须指定参数    
# define optional_argument  2    //参数可选    

flag和val相互依赖,主要分两种情况:
(1)、flag为NULL,val值用于确定该长选项,所以需要为长选项指定唯一的val值。这里也为长选项和短选项建立了桥梁。
(2)、flag不为NULL,则将val值存放到flag所指向的存储空间,用于标识该长选项出现过。

返回值:
程序中使用短选项,则返回短选项字符(如‘n'),当需要参数是,则在返回之前将参数存入到optarg中。
程序中使用长选项,返回值根据flag和val确定。当flag为NULL,则返回val值。所以根据val值做不同的处理,这也说明了val必须唯一。当val值等于短选项值,则可以使用短选项解析函数解析长选项;当flag不为NULL,则将val值存入flag所指向的存储空间,getopt_long返回0, 出现未定义的长选项或者短选项,getopt_long返回?, 解析完毕,getopt_long返回-1

例1:

#include <stdio.h>    
#include <stdlib.h>    
#include <getopt.h> //getopt_long()头文件位置    
    
int main(int argc, char** argv)    
{    
    const char *optstring="n:v";    
    int c,deb,index;    
    struct option opts[]={{"username",required_argument,NULL,'n'},    
                          {"version",no_argument,NULL,'v'},    
                          {"debug",no_argument,&deb,1},    
                          {0,0,0,0}};    
    while((c=getopt_long_only(argc,argv,optstring,opts,&index))!=-1)    
    {    
            
        switch(c)    
        {    
        case 'n'://-n 或者 --username 指定用户名    
            printf("username is %s\n",optarg);    
            break;    
        case 'v'://-v 或者--version,输出版本号    
            printf("version is 0.0.1 \n");    
            break;    
        case 0://flag不为NULL    
            printf("debug is %d\n",deb);    
            break;    
        case '?'://选项未定义    
            printf("?\n");    
            break;    
        default:    
            printf("c is %d\n",c);    
            break;    
        }    
    }    
    return 0;    
}    


例2:

#include <stdio.h>  
#include <stdlib.h>  
#include <getopt.h> //getopt_long()头文件位置  
  
int main(int argc, char** argv)  
{  
    const char *optstring="n:v";  
    int c,deb,index;  
    struct option opts[]={{"username",required_argument,0,0},  
                          {"n",required_argument,0,0},  
                          {"version",no_argument,0,0},  
                          {"v",no_argument,0,0},  
                          {"debug",no_argument,0,0},  
                          {"d",no_argument,0,0},  
                          {"help",no_argument,0,0},  
                          {"h",no_argument,0,0}};  
    while((c=getopt_long_only(argc,argv,optstring,opts,&index))!=-1)  
    {  
        switch(index){  // 没有定义返回值时则可采用索引的形式
            //-n或者--username  
            case 0:  
            case 1:  
                printf("username:%s\n",optarg);  
                break;  
            //-v或者--version  
            case 2:  
            case 3:  
                printf("version:1.0.0\n");  
                break;  
            //-d or --debug  
            case 4:  
            case 5:  
                printf("debug:yes\n");  
                break;  
            //-h or --help  
            case 6:  
            case 7:  
                printf("Help:?\n");  
                break;  
            default:  
                printf("other:%d\n",index);  
                break;  
        }  
    }  
    return 0;  
}  

  评论这张
 
阅读(100)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018