1. getopt函数申明
int getopt(int argc, char * const argv[],const char *optstring);
使用时需包含头文件 unistd.h
argc、argv:分别来自命令行传给main()函数的参数argc(参数个数)和argv(参数数组)。
optstring:是一个包含合法选项字符的字符串。
2. getopt函数的作用
getopt被用来解析命令行选项参数。也即对optstring中的选项字符的处理:
(1)选项字符后面跟一个冒号“:",则此选项后要带一个参数,可以通过全局变量 optarg来获取 。
(2)选项字符后面跟两个冒号“::“,则此选项的参数是可选的,即如果提供选项参数,则选项参数必须紧跟在选项字符后面,不能以空格隔开,如”o::",则命令行中应该是这样的"-oarg",同样用optarg获取,如果没有提供值,则optarg为0
(3)如果optstring包含“W;",即W后面一个分号,那么当命令行中出现“-W foo”,它们就会被当成是一个长选项,即“–foo”。
(4)如果optstring的第一个字符是冒号’:’,那么getopt() 不会打印错误信息,返回双引号’:’。默认情况下, getopt()会在标准错误中打印错误信息。
(5)如果输入的选项字符不在合法选项字符optstring中,getopt()函数返回“?”,并将错误的字符放在optopt全局变量中。
3. 与getopt相关的全局变量
extern int optind //下一次调用getopt的时,从optind存储的位置处重新开始检查选项。
extern int opterr //当opterr=0时,getopt不向stderr输出错误信息。
extern int optopt //当命令行选项字符不包括在optstring中或者选项缺少必要的参数时,该选项存储在optopt 中,getopt返回’?’
extern char *optarg //选项的参数指针,如果选项字符串里的字母后接着冒号“:”,则表示还有相关的参数,全域变量optarg 即会指向此额外参数。如果getopt()找不到符合的参数则会印出错信息,并将全域变量optopt设为“?”字符,如果不希望getopt()印出错信息,则只要将全域变量opterr设为0即可。
4. getopt()对参数处理的三种情况:
- 默认情况下,getopt()会在扫描时重新排列argv的内容。最终,所有非选项参数都会排在最后面。
- 如果optstring的第一个字符是 '+'或者设置了环境变量POSIXLY_CORRECT,那么一旦遇到非选项参数,就会停止处理选项(即不会重新排列)。
- 如optstring 第一个字符是 ‘-’,那么每一个非选项参数都将被处理,好似它们就是选项的参数。(也不会重新排列)
5. code示例
最快的方法还是看一段示例代码。上菜
#include <unistd.h> #include <stdio.h> int main(int argc,char * argv[]) { printf("%s\n","argv原序:"); for(int i = 0;i < argc; i++) { printf("%s ",argv[i]); } printf("\n"); printf("START@optind:%d,opterr:%d\n",optind,opterr); int ret; while((ret = getopt(argc,argv,"aW;b:c:de::")) != -1){ switch(ret) { case 'a': printf("having option -a\n"); break; case 'b': printf("having option -b,and its argument is %s\n",optarg); break; case 'c': printf("having option -c,and its argument is %s\n",optarg); break; case 'd': printf("Having option -d\n"); break; case 'e': printf("having option -e,it is optional,and its argument is %s\n",optarg); break; case '?': printf("Unknown option -%c\n",(char)optopt); break; } } printf("END@optind:%d,argv[%d]:%s\n",optind,optind,argv[optind]); printf("%s\n","argv现序:"); for(int i = 0;i <argc;i++) { printf("%s ",argv[i]); } printf("\n"); return 0; }
执行结果:
6. 一个选项传递多个参数
对于5的code示例,只是最基本的用法,有时候一个选项需要传递多个参数,如何实现呢?
#include <stdio.h> #include<unistd.h> int main(int argc, char *argv[]) { int ch; char *s1, *s2, *s3; char *s4, *s5; while((ch = getopt(argc,argv,"a:b:"))!= -1) { switch(ch) { case 'a' : s1=optarg; s2=argv[optind]; s3=argv[optind+1]; break; case 'b' : s4 = optarg; s5 = argv[optind]; break; default: printf("unrecongnized option :%c\n",ch); break; } printf("s1 = %s, s2 = %s, s3 = %s, s4 = %s, s5 = %s\n", s1, s2, s3, s4, s5); } return 0; }
编译结果:
至于为什么第一次打印的时候,s5是NULL,我还没搞清楚,有知道原因的看到了烦请指教
参看链接:
https://www.cnblogs.com/gjianw217/p/3288051.html
https://blog.csdn.net/weixin_40763897/article/details/87898328
https://blog.csdn.net/zhq651/article/details/8494324