getopt()函数详细解释!保证看明白

研究select模型的时候看到CSDN很多博主用到了getopt函数,这个模型弄的一脸懵,getopt先弄明白。。

getopt() 方法是用来分析命令行参数的,它的作用是判断你输入的命令行是否正确。

1.命令行组成

我们举例说明命令行组成

ls -l -a /etc

这行命令的意思是:详细列出/etc这个文件夹下所有文件,包括隐藏文件的信息

ls ++命令 (command)++

a 和l 都是 ++选项 (option)++,选项前面,必须有短横线这才叫选项

/etc 这叫++operand ,操作对象++

grep -i water aaa.log

这行命令的意思是:在aaa.log文件中,查找water字符串,不区分大小写

grep 命令

i 选项

water ,正则表达式中叫匹配模式pattern ,命令行中叫做 ++选项参数 ( option argument)++

aaa.log 操作对象

比方说我瞎写 了一个aaa.log 其中内容是

water

water222

333water

444aaabbcc

555line

footabl

footballwater lunch

aaawatersuper

那么上书命令的 执行结果是

water
water222

333water

footballwater lunch

aaawatersuper

然后很多命令有不止一个参数,继续拿grep举例

grep -f aaa.log water aaa.log

这个命令意思是:在结果中每一行都打印一遍aaa.log 这个文件名,在文件aaa.log中查找water字符串,不区分大小写。然后执行结果是

aaa.log:water

aaa.log:water222

aaa.log:333water

aaa.log:444aaabbcc

aaa.log:555line

aaa.log:footabl

aaa.log:footballwater lunch

aaa.log:aaawatersuper

我晕死,我也不知道-f怎么不匹配的现在也在结果中变红了匹配了,但是这先不重要,弄明白命令行的组成就行了

2. getopt函数

2.1 函数原型

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

2.2 参数argc argv是什么意思

argc是你在命令行中的所有参数个数,argv[]是所有参数组成的数组,外加可执行文件名

cpp 复制代码
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>

int main(int argc, char* argv[]){
    printf("参数个数是%d\n",argc);
    for(int i=0;i<argc;i++){
        printf("参数argv[%d] 是%s\n",i,argv[i]);
    }

return 0;
}

把这个代码gcc 编译成a.out

然后你 ./a.out hello world cat dog 回车,结果显示

参数个数是5

argv[0] 是 ./a.out

argv[1] 是 hello

argv[2] 是 world

argv[3] 是 cat

argv[4] 是 dog

2.3 。 这个函数有几个全局变量

getopt()函数有几个系统默认的全局变量,可以直接拿出来使用

  • optarg:当前选项的参数字符串 ,要么是null 要么是你写的,或者系统捕获的选项参数。
  • optind:下一个查找的位置,在所有命令行中的索引。
  • optopt:当发现无效选项字符时,optopt 就等于这个无效选项字符
  • opterr:1或者0 ,正常状态是1,表示打印错误
cpp 复制代码
//学习get_opt()
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>

int main(int argc, char* argv[]){
    printf("参数个数是%d\n",argc);
    for(int i=0;i<argc;i++){
        printf("参数argv[%d] 是%s\n",i,argv[i]);
    }
    printf("test getopt func\n");
    int ret;
    while ((ret=getopt(argc, argv,"abc:")) !=-1){
	printf("返回值ret =%d ,int optind= %d,它的选项参数optarg =%s, 错误选项optopt =%c\n",ret,optind,optarg,optopt);
    }
return 0;
}

我的初衷是,只有-a -b -c 是合法选项, -c 后面必须接参数, abc 可以不全,但是 c后面必须有参数 。下面来实验下我瞎写的参数 或者故意写错会报什么

2.3.1 完全正确的输入

我输入 ./test2 -a -b -c wang

参数个数是5

参数argv[0] 是./test2

参数argv[1] 是-a

参数argv[2] 是-b

参数argv[3] 是-c

参数argv[4] 是wang

test getopt func

返回值ret =97 ,int optind= 2,它的选项参数optarg =(null), 错误选项optopt =

返回值ret =98 ,int optind= 3,它的选项参数optarg =(null), 错误选项optopt =

返回值ret =99 ,int optind= 5,它的选项参数optarg =wang, 错误选项optopt =

都对,所以到最后也没抓到哪个参数错误 (optopt一直是空的)

2.3.2 有一个不该出现的参数

./test2 -a -b -d wang

参数个数是5

参数argv[0] 是./test2

参数argv[1] 是-a

参数argv[2] 是-b

参数argv[3] 是-d

参数argv[4] 是wang

test getopt func

返回值ret =97 ,int optind= 2,它的选项参数optarg =(null), 错误选项optopt =

返回值ret =98 ,int optind= 3,它的选项参数optarg =(null), 错误选项optopt =

./test2: invalid option -- 'd'

返回值ret =63 ,int optind= 4,它的选项参数optarg =(null), 错误选项optopt =d

2.3.3 打乱参数顺序

./test2 -b -c -d wang

参数个数是5

参数argv[0] 是./test2

参数argv[1] 是-b

参数argv[2] 是-c

参数argv[3] 是-d

参数argv[4] 是wang

test getopt func

返回值ret =98 ,int optind= 2,它的选项参数optarg =(null), 错误选项optopt =

返回值ret =99 ,int optind= 4,它的选项参数optarg =-d, 错误选项optopt =

没抓到错误,因为 选项c 后面的-d被认为是选项参数了,后面的wang酒忽略不看了。

未完待续额,后面写getopt _long

相关推荐
Peter·Pan爱编程10 分钟前
Docker在Linux中安装与使用教程
linux·docker·eureka
kunge20131 小时前
Ubuntu22.04 安装virtualbox7.1
linux·virtualbox
清溪5491 小时前
DVWA中级
linux
m0_748254091 小时前
2025最新华为云国际版注册图文流程-不用绑定海外信用卡注册
服务器·数据库·华为云
MUY09901 小时前
应用控制技术、内容审计技术、AAA服务器技术
运维·服务器
楠奕1 小时前
elasticsearch8.12.0安装分词
运维·jenkins
Sadsvit2 小时前
源码编译安装LAMP架构并部署WordPress(CentOS 7)
linux·运维·服务器·架构·centos
xiaok2 小时前
为什么 lsof 显示多个 nginx 都在 “使用 443”?
linux
java资料站2 小时前
Jenkins
运维·jenkins
苦学编程的谢3 小时前
Linux
linux·运维·服务器