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
---------------------