Linux下解析命令行的标准形参(getopt)

举报
DS小龙哥 发表于 2021/12/04 23:13:39 2021/12/04
【摘要】 一、前言 在Linux下开发时,命令行的使用是必不可少的,经常会在命令行运行各种命令,启动服务,启动应用程序,查看函数用法等等;运行这些命令时都会传入一些参数,比如: $ ./c_app 127.0....

一、前言

在Linux下开发时,命令行的使用是必不可少的,经常会在命令行运行各种命令,启动服务,启动应用程序,查看函数用法等等;运行这些命令时都会传入一些参数,比如:

$ ./c_app 127.0.0.1 8888 小明
$ man printf

  
 
  • 1
  • 2

这些命令行参数解析,Linux提供了一套函数,可以很方便的解析传入的各种参数信息。

这篇文章就介绍如何使用Linux提供的解析函数,完成命令的行的参数解析。

函数原型如下:

#include <unistd.h>
#include <getopt.h>3个是全局变量
extern char *optarg;
extern int optind, opterr, optopt;
功能介绍:
optarg——指向当前选项参数(如果有)的指针。  比如: cp 123.c 888/ -fv 、 gcc 123.c -o app
optind——再次调用 getopt() 时的下一个 argv 指针的索引。
optopt——最后一个已知选项。

int getopt(int argc, char * const argv[],const char *optstring);
函数功能: 解析短选项形参. 只能解析单个字符.

函数参数:
int argc   就是main函数传入的argc 
char * const argv[]  就是main函数传入的argv
const char *optstring  将要解析的选项形参格式.
比如: "a:b:c:v"    字母后面跟着冒号就表示该选项形参必须传递参数.
传入形参的时候: a.out -a 666 -b 777 -c 888 -v

返回值:
解析成功就返回当前解析的选项形参的字符. 并且会给全局变量赋值. optarg这个指针就会指向该选项形参后面的数据地址.
如果失败就返回-1   解析错误会返回? 

int getopt_long(int argc, char * const argv[],
         const char *optstring,
         const struct option *longopts, int *longindex);
函数功能:解析长选项形参.
struct option {
   const char *name;   表示要解析的长选项字符串  --abc
   int         has_arg;   0表示不需要参数 1表示必须要 2表示可选
   int        *flag;     一般NULL
   int         val;      当解析到正确的长选项形参的时返回的字符  k
};


int getopt_long_only(int argc, char * const argv[],
         const char *optstring,
         const struct option *longopts, int *longindex);
函数功能:同时支持解析长选项形参和短选项形参.

  
 
  • 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
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

二、案例代码

2.1 解析命令行的短选项形参

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>

int main(int argc,char **argv)
{
    int c;
    while(1)
    {
        //解析传入的选项参数   ./a.out -a 123 -b 456 -c 789 -v
        c=getopt(argc,argv,"a:b:c:v?");
        if(c==-1)break;
        switch(c)
        {
        case 'a':
            printf("当前的选项形参:a,值:%s\n",optarg);
            break;
        case 'b':
            printf("当前的选项形参:b,值:%s\n",optarg);
            break;
        case 'c':
            printf("当前的选项形参:c,值:%s\n",optarg);
            break;
        case 'v':
            printf("当前版本:1.2.3\n");
            break;
        case '?':
            printf("用法:./a.out [-a 123 -b 456 -c 789 -v] \n");
            break;   
        default:
            break;
        }
    }
    return 0;
}

[wbyq@wbyq linux_c]$ ./a.out -a 123 -b 67 -c 999
当前的选项形参:a,:123
当前的选项形参:b,:67
当前的选项形参:c,:999
[wbyq@wbyq linux_c]$ ./a.out -a
./a.out: option requires an argument -- 'a'
用法:./a.out [-a 123 -b 456 -c 789 -v] 
[wbyq@wbyq linux_c]$ ./a.out -?
用法:./a.out [-a 123 -b 456 -c 789 -v] 
[wbyq@wbyq linux_c]$ ./a.out -v
当前版本:1.2.3
[wbyq@wbyq linux_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
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55

2.2 解析命令行的长选项形参

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>

struct option opt_list[]=
{
    {"a123",1,NULL,'a'},
    {"b123",1,NULL,'b'},
    {"c123",1,NULL,'c'},
    {"help",0,NULL,'?'},
};

int main(int argc,char **argv)
{
    int c;
    while(1)
    {
        //解析传入的选项参数   ./a.out -a 123 -b 456 -c 789 -v
        c=getopt_long(argc,argv,"a:b:c:v?",opt_list,NULL);
        if(c==-1)break;
        switch(c)
        {
        case 'a':
            printf("当前的选项形参:a,值:%s\n",optarg);
            break;
        case 'b':
            printf("当前的选项形参:b,值:%s\n",optarg);
            break;
        case 'c':
            printf("当前的选项形参:c,值:%s\n",optarg);
            break;
        case 'v':
            printf("当前版本:1.2.3\n");
            break;
        case '?':
            printf("用法:./a.out [-a 123 -b 456 -c 789 -v] \n");
            break;   
        default:
            break;
        }
    }
    return 0;
}

[wbyq@wbyq linux_c]$ ./a.out -a 12345
当前的选项形参:a,:12345
[wbyq@wbyq linux_c]$ ./a.out --a123 12345
当前的选项形参:a,:12345
[wbyq@wbyq linux_c]$ ./a.out -?
用法:./a.out [-a 123 -b 456 -c 789 -v] 
[wbyq@wbyq linux_c]$ ./a.out --help
用法:./a.out [-a 123 -b 456 -c 789 -v] 
[wbyq@wbyq linux_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
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60

2.3 解析复杂的命令行选项形参

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>

struct option opt_list[]=
{
    {"a123",1,NULL,'a'},
    {"b123",1,NULL,'b'},
    {"c123",1,NULL,'c'},
    {"help",0,NULL,'?'},
};

int main(int argc,char **argv)
{
    int c;
    while(1)
    {
        //解析传入的选项参数   ./a.out -a 123 -b 456 -c 789 -v
        c=getopt_long_only(argc,argv,"a:b:c:v?",opt_list,NULL);
        if(c==-1)break;
        switch(c)
        {
        case 'a':
            printf("当前的选项形参:a,值:%s\n",optarg);
            break;
        case 'b':
            printf("当前的选项形参:b,值:%s\n",optarg);
            break;
        case 'c':
            printf("当前的选项形参:c,值:%s\n",optarg);
            break;
        case 'v':
            printf("当前版本:1.2.3\n");
            break;
        case '?':
            printf("用法:./a.out [-a 123 -b 456 -c 789 -v] \n");
            break;   
        default:
            break;
        }
    }
    return 0;
}

[wbyq@wbyq linux_c]$ ./a.out 
[wbyq@wbyq linux_c]$ ./a.out -a 1234
当前的选项形参:a,:1234
[wbyq@wbyq linux_c]$ ./a.out -a123 1234
当前的选项形参:a,:1234
[wbyq@wbyq linux_c]$ ./a.out --a123 1234
当前的选项形参:a,:1234


  
 
  • 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
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58

文章来源: xiaolong.blog.csdn.net,作者:DS小龙哥,版权归原作者所有,如需转载,请联系作者。

原文链接:xiaolong.blog.csdn.net/article/details/121624097

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。