getopt()函数详解

1、函数原型

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

2、含义

解析命令行参数。

Linux命令格式如下:

  • 命令 [-选项] [参数]

  • cmd [-option] [paramater]

例如:

  • cmd -a -b

  • cmd -a aParamater -b bParamater

其中带-的表示【选项】,后面跟着的是选项对应的参数。

3、参数

参数含义
argc命令参数选项个数。执行命令时调用main函数,并从main函数传入
argv命令行参数选项内容
optstring命令所支持的选项字符的集合,通常为一个字符串
例如:命令ls -la,参数为la,optstring可以为“la”,
后面会详细讲述optstring格式与含义

4、返回值

备注1:该函数调用时需要在循环中进行调用,故每循环调用一次都会有一个返回值。

备注2:返回值为int类型,因为每个字符其实本身也是对应一个int值的,故虽然为int型,返回值可以是一个字符。

返回值含义
-1当返回-1表示argv中的参数已经全部解析完成。(即:命令传入的参数)
参数选项字符解析出命令的【参数选项字符】,若该选项带有参数,则全局变量optarg会指向该参数。
表示传入的参数不合法。即:不是optstring字符串中指定的【选项字符】

5、optstring参数详解

形参含义:

optstring表示命令参数选项的集合,用字符串表示,字符串中的每一个字符表示一个合法选项。

例如:某个命令cmd支持选项-a -b -c -d -e -f -g,则形参optstring可以是:
"abcdefg"

一个完整的optstring字符串由【字符】、【冒号】、【双冒号】组成,其中冒号和双冒号非必定出现。

例如,下面形参optstring都是合法的:
"abcdefg"
"ab:cd::efg"
"a:bcde::fg::"

【冒号】or【双冒号】是跟随在选项字符后面的,表示该选项是否带有参数。具体含义见下表格

字符后面是否有冒号具体含义
无冒号该选项不带参数,直接使用即可,格式为 cmd [-option]
单冒号该选项后必须带有参数,格式为 cmd [-option] [para]
双冒号该选项后可以有参数,也可以无参数
例如:
    当optstring为 "a:bde::f" 时,
表示:
    命令有abdefg几个选项,
其中:
    a 后有一个单冒号,所以必须跟有参数,不跟参数会报错。使用格式为  cmd -a para 或 cmd -apara(注意:选项跟参数之间可以有空格,可以没有空格,这点一定要跟双冒号区分开)
    bdf 后没有冒号,所以无参数,直接使用即可,格式为  cmd -b -d -f 或 cmd -bdf(可以连在一起写)
    e 后面有双冒号,表示选项e后面参数可有可无。使用格式为  cmd -e 或 cmd -epara(注意:当有参数时参数跟选项之间必须保持相连,没有空格!否则会报错)

6、4个全局变量

库中定义了4个全局变量跟该函数息息相关(这些全局变量我们可以直接使用):

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

当调用该函数的时候,会根据不同的结果对下面四个全局变量进行对应置位:

变量名含义置位场景
optarg指向当前选项对应的参数例如命令:cmd -a apara
当解析到参数-a时,则optarg指向字符串"apara"
optind
opterr是否将错误log打印到stderr该变量默认值为1,即:默认会将错误日志打印到stderr。
当我们不想看到终端上打印错误日志,可以将该变量赋值为0
optopt保存无法识别的选项当解析命令选项时,发现某个选项不能识别,则保存该选项到optopt中,并将错误信息打印到opterr中。

7、代码示例

7.1 练习题

当前有几个系统:

  • Linux、Qnx、Windows、Android等,

设计命令作用:

  • 输入命令,通过对应参数打印操作系统全名

命令格式为:

  • systemis [-option] [para]

其中:

  • option可选项为:
  • -a 代表Android系统
  • -l 代表Linux系统
  • -q 代表Qnx系统
  • -w 代表Windows系统
  • -o 代表其他系统,需要用户自行输入
  • -A 代表打印所有操作系统,用户输入啥打印啥,用户输入空则不打印任何字符

7.2 代码展示

getopt.c

/* 版权声明
 * 功能     :
 * 作者     :lsy
 * 文件路径 : /home/lsy/practice/c/getopt/getopt.c
 * 创建时间 :2020/05/08 15:55
 */

#include <stdio.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
    int oc;
    int i = 1;

    //opterr = 0; /* 默认值为1,想关闭错误log打印,将该变量设置为0即可 */

    if (argc <= 1) {
        printf("Usage:\r\n");
        printf("    %s [option] [para]\r\n", argv[0]);
        printf("    option can be : -a -l -q -w -o -A\r\n");
    }

    do {
        oc = getopt(argc, argv, "alqwo:A::");
        if(oc == (-1)) {
            break;
        }

        printf("---------------------\r\n");
        printf("times:%d\r\n", i++);
        printf("optarg = %s\r\n", optarg);
        printf("optind = %d\r\n", optind);
        printf("opterr = %d\r\n", opterr);
        printf("optopt = %d\r\n", optopt);

        switch(oc) {
            case 'a':
                printf("System is Android.\r\n");
                break;
            case 'l':
                printf("System is Linux.\r\n");
                break;
            case 'q':
                printf("System is Qnx.\r\n");
                break;
            case 'w':
                printf("System is Windows.\r\n");
                break;
            case 'o':
                printf("System is %s.\r\n", optarg);
                break;
            case 'A':
                printf("All system are : %s.\r\n", optarg);
                break;
            case '?':
                printf("case ? branch : return value is %d\r\n", oc);
                break;
            case ':':
                printf("case : branch : return value is %d\r\n", oc);
                break;
        }

        printf("---------------------\r\n");
    } while(oc != (-1));

    return 0;
}

Makefile:

systemis: getopt.c
	gcc $^ -o $@

clean:
	rm -rf systemis

7.3 结果展示

结果1:

lsy@ubuntu18:~/practice/c/getopt$ ./systemis -a
---------------------
times:1
optarg = (null)
optind = 2
opterr = 1
optopt = 0
System is Android.
---------------------

结果2:-o后面有单冒号,不输入参数时候会报错

lsy@ubuntu18:~/practice/c/getopt$ ./systemis -o
./systemis: option requires an argument -- 'o'   <------- 错误log,-o选项后面单冒号,必须有参数
---------------------
times:1
optarg = (null)
optind = 2
opterr = 1
optopt = 111
case ? branch : return value is 63
---------------------
lsy@ubuntu18:~/practice/c/getopt$ ./systemis -o FreeRTOS
---------------------
times:1
optarg = FreeRTOS
optind = 3
opterr = 1
optopt = 0
System is FreeRTOS.
---------------------

结果3:

lsy@ubuntu18:~/practice/c/getopt$ ./systemis -lwb
---------------------
times:1
optarg = (null)
optind = 1
opterr = 1
optopt = 0
System is Linux.
---------------------
---------------------
times:2
optarg = (null)
optind = 1
opterr = 1
optopt = 0
System is Windows.
---------------------
./systemis: invalid option -- 'b'    <------- 错误log,-b为不合法参数
---------------------
times:3
optarg = (null)
optind = 2
opterr = 1
optopt = 98
case ? branch : return value is 63
---------------------
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值