函数原型
#include <unistd.h>
extern char *optarg;
extern int optind;
extern int optopt;
extern int opterr;
extern int optreset;
int getopt(int argc, char * const *argv, const char *optstring);
函数参数
前两个参数 argc 和argv 来自main 函数的参数,optstring 则是“选项字符串”
成员
- char* optarg:用来保存选项的参数
- int optind:记录下一个检索位置
- int opterr:是否将错误信息输出到stderr,为0时表示不输出
- int optopt:表示不在选项字符串optstring中的选项
例如执行命令:
./test -c test.conf # 这里-c 就是选项, test.conf 就是-c 的参数
./test -ab # 这里-ab是两个不带参数的选项
测试代码一,只识别一个选项,其他视为错误:
#include <stdio.h>
#include <unistd.h>
using namespace std;
int main(int argc, char * argv[])
{
int ch;
printf("optind:%d,opterr:%d\n",optind,opterr);
printf("--------------------------\n");
while ((ch = getopt(argc, argv, "a")) != -1)
{
printf("optind: %d\n", optind);
switch (ch)
{
case 'a':
printf("HAVE option: -a\n\n");
break;
case '?':
printf("Unknown option: %c\n",(char)optopt);
break;
}
}
return 0;
}
编译,分别尝试以下执行方式:
./a.out # 没有option
./a.out -a # HAVE option: -a,a的optind 是2
./a.out -ab # Unknown option: b ,这里 optopt 就是b了
./a.out -a b # HAVE option: -a ,a 的 optind 是2; Unknown option: b,b的optind 是3
测试代码二,只识别一个选项,选项后跟冒号,代表必须有一个参数,可以紧挨着选项或者分离:
#include <stdio.h>
#include <unistd.h>
using namespace std;
int main(int argc, char * argv[])
{
int ch;
printf("optind:%d,opterr:%d\n",optind,opterr);
printf("--------------------------\n");
while ((ch = getopt(argc, argv, "a:")) != -1)
{
printf("optind: %d\n", optind);
switch (ch)
{
case 'a':
printf("HAVE option: -a\n\n");
printf("The argument of -a is %s\n\n", optarg);
break;
case 'b':
printf("HAVE option: -b\n\n");
break;
case '?':
printf("Unknown option: %c\n",(char)optopt);
break;
}
}
return 0;
}
分别测试以下输入:
./a.out -a # Unknown option: a,指定要带参数但实际没有给参数,不识别
./a.out -a1 # HAVE option: -a,The argument of -a is 1,optind: 2
./a.out -a 1 # HAVE option: -a,The argument of -a is 1,optind: 3 (为啥是3??)
./a.out -b # Unknown option -b
测试代码三,只识别一个选项,选项后跟双冒号,代表可以有一个参数,如果有参数必须紧挨着选项:
#include <stdio.h>
#include <unistd.h>
using namespace std;
int main(int argc, char * argv[])
{
int ch;
printf("optind:%d,opterr:%d\n",optind,opterr);
printf("--------------------------\n");
while ((ch = getopt(argc, argv, "a::")) != -1)
{
printf("optind: %d\n", optind);
switch (ch)
{
case 'a':
printf("HAVE option: -a\n\n");
printf("The argument of -a is %s\n\n", optarg);
break;
case '?':
printf("Unknown option: %c\n",(char)optopt);
break;
}
}
return 0;
}
分别输入:
./a.out -a # HAVE option: -a The argument of -a is (null) optind: 2
./a.out -a1 # HAVE option: -a The argument of -a is 1 optind: 2
./a.out -a 1 # HAVE option: -a The argument of -a is (null) optind: 2
测试代码四,一个较长的选项:
#include <stdio.h>
#include <unistd.h>
using namespace std;
int main(int argc, char * argv[])
{
int ch;
printf("optind:%d,opterr:%d\n",optind,opterr);
printf("--------------------------\n");
while ((ch = getopt(argc, argv, "a:b::cd")) != -1)
{
printf("optind: %d\n", optind);
switch (ch)
{
case 'a':
printf("HAVE option: -a\n\n");
printf("The argument of -a is %s\n\n", optarg);
break;
case 'b':
printf("HAVE option: -b\n\n");
printf("The argument of -b is %s\n\n", optarg);
break;
case 'c':
printf("HAVE option: -c\n\n");
printf("The argument of -c is %s\n\n", optarg);
break;
case 'd':
printf("HAVE option: -d\n\n");
printf("The argument of -d is %s\n\n", optarg);
break;
case '?':
printf("Unknown option: %c\n",(char)optopt);
break;
}
}
return 0;
}
./a.out -a1 -b1 -cd
输出:
optind:1,opterr:1
--------------------------
optind: 2
HAVE option: -a
The argument of -a is 1
optind: 3
HAVE option: -b
The argument of -a is 1
optind: 3
HAVE option: -c
The argument of -c is (null)
optind: 4
HAVE option: -d
The argument of -d is (null)
参考: