linux选项解释-getopt和getopt_long函数

1、命令行简介

解释分析命令行通常是程序的第一个任务,C语言通过argc和argv参数来访问它的命令行参数。
最简单的命令行处理技术可以通过if判断来表示,如下例:

if(argc>1 && argv[1][0] == '-' && argv[1][1] == 'h')    //判断命令行参数是否为-n
{
    do_some thing();
}

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

2、getopt函数

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()到两个参数传递而来。optsting是选项参数组成的字符串,如果该字符串里任一字母后有冒号,那么这个选项就要求有参数,optarg就是选项参数。optind是当前索引,optopt用于当发现无效选项字符的时候,getopt函数或者返回 “?”或者返回“:”字符,并且optopt包含了所发现的无效选项字符。

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

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

例子:

#include <stdio.h>
#include <unistd.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;
}  

3、getopt_long函数

getopt_long函数用来处理长选项,其声明如下:

#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结构称为长选项表,其声明如下:

struct option {  
    char *name;  
    int has_arg;  
    int *flag;  
    int val;  
};
longindex参数如果没有设置为NULL,那么它就指向一个变量,这个变量会被赋值为寻找到的长选项在longopts中的索引值。

结构中的元素解释如下:

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中出现的这个选项的参数相同;


一般每个长选项都对应一个短选项,两者是等价的,option结构就是用来定义长选项对应哪个短选项,name表示长选项的名称,val表示对应的短选项,比如{ "no-proxy", no_argument, NULL, 'N' },说明--no-proxy对应与-N。

假设使用下载工具axel:

axel -q --no-proxy --max-speed=150 http://blog.csdn.net/kenby/index.html

初始时,optind的值为1,指向第1个参数,每调用一次getopt_long,optind就向后移一个单位,指向第二个参数,这样optind总是指向下一个要处理的参数,optarg表示参数的值,比如但处理max-speed时,optarg的值为150


函数返回值:

(1)若没有命令行参数,返回-1

(2)若碰到匹配的短选项, 返回对应的字符,比如碰到-N, 返回'N',若碰到匹配的长选项,返回在option数组里面定义的val,

比如碰到--no-proxy, 返回'N'。

(3)若碰到无法识别的短选项,返回-1, 若碰到无法识别的长选项,返回'?'


例子:

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


你可能感兴趣的:(getopt,getopt_long,命令行解析)