getopt函数,命令选项解析函数的分析
来源:互联网 发布:汽车解剖软件 编辑:程序博客网 时间:2024/06/06 04:16
Linux下getopt()函数的使用
简述:在linux下我们都熟悉,假设我的程序编译后生成可执行文件为cct,在自己编译的程序运行前我们会输入
./cct -选项 + 参数(可有可无),而这里的选项和参数将被传入给main函数,使用getopt()函数进行解析,和参数匹配等从而发挥用户想达成的作用;
具体用法解释如下:
getopt()函数包含于unistd.h头文件中,是用来解析命令行选项和参数意义分析的函数;
函数原型如下:
int getopt(int argc,char * const argv[ ],const char * optstring);
前两个参数是main()函数的两个参数!
第三个参数是个字符串,我们可以叫他选项字符串;
返回值为int类型,我们都知道char类型是可以转换成int类型的,每个字符都有他所对应的整型值,其实这个返回值返回的就是一个字符,叫选项字符;
下面具体了解下getopt()函数的作用吧;
与此函数有关的几个全局变量:
extern char* optarg;
extern int optind;
extern int opterr;
extern int optopt;
1.保存选项的参数的;
2.用来记录下一个检索位置;
3.表示的是是否将错误信息输出到stderr,为0时表示不输出;
4.表示不在选项字符串optstring中的选项;
在linux下大家都用过这样一条指令:gcc helloworld.c -o helloworld.out; 这条指令中的-o就是命令行的选项,而后面的helloworld.out就是-o选项所携带的参数。当然熟悉shell指令的人都知道,有些选项是不用带参数的,而这样不带参数的选项可以写在一起,比如说有两个选项-c和-d,这两个选项都不带参数,那么他们是可以写在一起,写成-cd的。实际的例子:当我们删除一个文件夹时可以使用指令 rm 目录名 -rf,本来-r表示递归删除,就是删除文件夹中所有的东西,-f表示不提示就立刻删除,他们两个都不带参数,这时他们就可以写在一起。
"a:b:cd::e",这就是一个选项字符串。对应到命令行就是-a ,-b ,-c ,-d, -e 。冒号又是什么呢? 冒号表示参数,一个冒号就表示这个选项后面必须带有参数(没有带参数会报错哦),但是这个参数可以和选项连在一起写,也可以用空格隔开,比如-a123 和-a 123都表示123是-a的参数;两个冒号的就表示这个选项的参数是可选的,即可以有参数,也可以没有参数,但要注意有参数时,参数与选项之间不能有空格,这一点和一个冒号时是有区别的。
例:
#include <unistd.h>
#include <stdio.h>
int main(int argc, char * argv[])
{
int ch;
printf("\n\n");
printf("optind:%d,opterr:%d\n",optind,opterr);
printf("--------------------------\n");
while ((ch = getopt(argc, argv, "ab:c:de::")) != -1)
{
printf("optind: %d\n", optind);
switch (ch)
{
case 'a':
printf("HAVE option: -a\n\n");
break;
case 'b':
printf("HAVE option: -b\n");
printf("The argument of -b is %s\n\n", optarg);
break;
case 'c':
printf("HAVE option: -c\n");
printf("The argument of -c is %s\n\n", optarg);
break;
case 'd':
printf("HAVE option: -d\n");
break;
case 'e':
printf("HAVE option: -e\n");
printf("The argument of -e is %s\n\n", optarg);
break;
case '?':
printf("Unknown option: %c\n",(char)optopt);
break;
}
}
}
复制代码
编译后命令行执行:# ./main -b "qing er"
输出结果为:
optind:1,opterr:1
--------------------------
optind: 3
HAVE option: -b
The argument of -b is qing er
我们可以看到:optind和opterr的初始值都为1,前面提到过opterr非零表示产生的错误要输出到stderr上。那么optind的初值为什么是1呢?
这就要涉及到main函数的那两个参数了,argc表示参数的个数,argv[]表示每个参数字符串,对于上面的输出argc就为3,argv[]分别为: ./main 和 -b 和"qing er" ,实际上真正的参数是用第二个-b 开始,也就是argv[1],所以optind的初始值为1;
当执行getopt()函数时,会依次扫描每一个命令行参数(从下标1开始),第一个-b,是一个选项,而且这个选项在选项字符串optstring中有,我们看到b后面有冒号,也就是b后面必须带有参数,而"qing er"就是他的参数。所以这个命令行是符合要求的。至于执行后optind为什么是3,这是因为optind是下一次进行选项搜索的开始索引,也是说下一次getopt()函数要从argv[3]开始搜索。当然,这个例子argv[3]已经没有了,此时getopt()函数就会返回-1。
再看一个输入:
./main -b "qing er" -c1234
输出结果为:
optind:1,opterr:1
--------------------------
optind: 3
HAVE option: -b
The argument of -b is qing er
optind: 4
HAVE option: -c
The argument of -c is 1234
对于这个过程会调用三次getopt()函数,和第一个输入一样,是找到选项-b和他的参数"qing er",这时optind的值为3,也就意味着,下一次的getopt()要从argv[3]开始搜索,所以第二次调用getopt()函数,找到选项-c和他的参数1234(选项和参数是连在一起的),由于-c1234写在一起,所以他两占一起占用argv[3],所以下次搜索从argv[4]开始,而argv[4]为空,这样第三次调用getopt()函数就会返回-1,循环随之结束。
接下来我们看一个错误的命令行输入: ./main -z 123
输出为:
optind:1,opterr:1
--------------------------
./main: invalid option -- 'z'
optind: 2
Unknown option: z
其中./main: invalid option -- 'z'就是输出到stderr的错误输出。如果把opterr设置为0那么就不会有这条输出。
在看一个错误的命令行输入: ./main -zheng
optind:1,opterr:1
--------------------------
./main: invalid option -- 'z'
optind: 1
Unknown option: z
./main: invalid option -- 'h'
optind: 1
Unknown option: h
optind: 2
HAVE option: -e
The argument of -e is ng
前面提到过不带参数的选项可以写在一起,所以当getopt()找到-z的时候,发现在optstring 中没有,这时候他就认为h也是一个选项,也就是-h和-z写在一起了,依次类推,直到找到-e,发现optstring中有。
最后要说明一下,getopt()会改变argv[]中参数的顺序。经过多次getopt()后,argv[]中的选项和选项的参数会被放置在数组前面,而optind 会指向第一个非选项和参数的位置。看例子
#include <unistd.h>
#include <stdio.h>
int main(int argc, char * argv[])
{
int i;
printf("--------------------------\n");
for(i=0;i<argc;i++)
{
printf("%s\n",argv[i]);
}
printf("--------------------------\n");
//int aflag=0, bflag=0, cflag=0;
int ch;
printf("\n\n");
printf("optind:%d,opterr:%d\n",optind,opterr);
printf("--------------------------\n");
while ((ch = getopt(argc, argv, "ab:c:de::")) != -1)
{
printf("optind: %d\n", optind);
switch (ch)
{
case 'a':
printf("HAVE option: -a\n\n");
break;
case 'b':
printf("HAVE option: -b\n");
printf("The argument of -b is %s\n\n", optarg);
break;
case 'c':
printf("HAVE option: -c\n");
printf("The argument of -c is %s\n\n", optarg);
break;
case 'd':
printf("HAVE option: -d\n");
break;
case 'e':
printf("HAVE option: -e\n");
printf("The argument of -e is %s\n\n", optarg);
break;
case '?':
printf("Unknown option: %c\n",(char)optopt);
break;
}
}
printf("----------------------------\n");
printf("optind=%d,argv[%d]=%s\n",optind,optind,argv[optind]);
printf("--------------------------\n");
for(i=0;i<argc;i++)
{
printf("%s\n",argv[i]);
}
printf("--------------------------\n");
}
命令行:./main zheng -b "qing er" han -c123 qing
输出结果为:
--------------------------
./main
zheng
-b
qing er
han
-c123
qing
--------------------------
optind:1,opterr:1
--------------------------
optind: 4
HAVE option: -b
The argument of -b is qing er
optind: 6
HAVE option: -c
The argument of -c is 123
----------------------------
optind=4,argv[4]=zheng
--------------------------
./main
-b
qing er
-c123
zheng
han
qing
--------------------------
可以看到最开始argv[]内容为:
./main
zheng
-b
qing er
han
-c123
qing
在执行了多次getopt后变成了
./main
-b
qing er
-c123
zheng
han
qing
阅读全文
0 0
- getopt函数,命令选项解析函数的分析
- python的命令解析getopt.getopt()函数分析
- 解析命令行选项参数的 getopt函数
- 选项解析:getopt() 和 getopt_long()函数
- 命令行程序选项解析函数—getopt
- 命令行程序选项解析函数—getopt
- 命令行程序选项解析函数—getopt
- 解析命令行选项参数函数getopt()
- 命令行选项参数解析-getopt函数
- 选项解析函数getopt()和getopt_long()
- 几个强大的linux命令和命令解析函数getopt()
- 命令行选项解析函数(C语言):getopt()和getopt_long()
- 命令行选项解析函数(C语言):getopt()、getopt_long()和getopt_long_only
- Getopt:命令行解析函数
- getopt()函数解析
- getopt函数解析
- getopt解析函数
- 使用getopt命令解析shell脚本的命令行选项
- Children's Game UVA
- Unknown error: Unable to build: the file dx.jar was not loaded from the SDK folder!
- Java 任务调度框架 Quartz《一》
- sed 命令 解析及使用
- 深入解析array_merge函数的用法 php
- getopt函数,命令选项解析函数的分析
- 什么是分布式系统
- Servlet
- BZOJ 4569: [Scoi2016]萌萌哒 并查集+倍增
- 我的面经
- Linux学习笔记--Tcpdump
- Qt 非静态成员函数作为线程函数?
- Java并发编程:volatile关键字解析
- 聊天功能,实现:每增加一条消息整体往上移动,滚动查看聊天记录