转载请注明出处:http://blog.csdn.net/zhangyang0402/archive/2010/06/14/5671410.aspx
命令行工具下的参数选项有两种,长选项和短选项。短选项以-开头,后面跟单个字母;长选项以--开头,后面可跟多个字母。
功能:解析命令行短选项参数
函数原型:
#include <getopt.h>
int getopt(int argc, char * const argv[], const char *optstring);
几个外部变量
extern char *optarg;
extern int optind, opterr, optopt;
optarg:若短选项后有参数,则optarg指向该参数
optind:扫描选项时,标识下一个选项的索引;扫描结束后,标识第一个非选项参数索引
opterr:出现不可识别的选项时,getopt将打印错误信息。将opterr设为0,可不打印错误信息。
optopt:存放不可识别的选项至optopt
1. 参数
argc:参数的个数(main)
argv:参数数组(main)
optstring:短选项字符集合,如 -i -n中的i,n
若选项后面有参数,则选项字符后加:, 对应的参数值保存在外部变量optarg中
如optstring 为"i:a",则表示程序支持两个短选项 -i arg和-a, -i后面须有参数值
当执行./a.out -i filename -a时,optarg指针就指向filename
2. 解析过程
getopt首先扫描argv[1]到argv[argc-1],并将选项及参数依次放到argv数组的最左边,非选项参数依次放到argv的最后边
如执行程序为:
0 1 2 3 4 5 6 7 8 9
$ ./mygetopt file1 -i infile -a -o outfile -v -h file2
扫描过程中,optind是下一个选项的索引, 非选项参数将跳过,同时optind增1。optind初始值为1。当扫描argv[1]时,为非选项参数,跳过,optind=2;扫描到-i选项时,后面有参数,下一个将要扫描的选项是-a,则optind更改为4;扫描到-a选项时,下一个选项是-o,optind=5;扫描到-o选项时,后面有参数,下一个选项是-v,optind=7;扫描到-v选项时,下一个选项是-h,optind=8;扫描到-h选项时,optind=9
扫描结束后,getopt会将argv数组修改成下面的形式
0 1 2 3 4 5 6 7 8 9
$./mygetopt -i infile -a -o outfile -v -h file1 file2
同时,optind会指向非选项的第一个参数,如上面,optind将指向file1
3. 返回值
若getopt找到短选项字符,则返回该选项字符;
若出现不能接受的选项字符或丢失选项参数,则返回?,同时optopt将被设置成相应选项字符;
则后面没有选项字符,则返回-1
4. 测试
mygetopt.c
#include<stdio.h> #include<getopt.h> void usage(const char *p); int main(int argc, char *argv[]) { int ch=0; opterr=0; // prevent error information to print for unrecognized options while( (ch=getopt(argc, argv, "i:ao:vh") ) != -1 ) { switch(ch) { case 'i': printf("option i: %s/n", optarg); printf("optind=%d/n/n", optind); break; case 'a': printf("option a :%c/n", ch); printf("optind=%d/n/n", optind); break; case 'o': printf("option o: %s/n", optarg); printf("optind=%d/n/n", optind); break; case 'v': printf("option v: %c/n", ch); printf("optind=%d/n/n", optind); break; case 'h': usage(argv[0]); printf("optind=%d/n/n", optind); break; default: printf("unrecognized option: %c/n", optopt); usage(argv[0]); } } if ( optind < argc ) { printf("/nnon-option arguments below:/n"); while( optind < argc ) { printf("%s/n", argv[optind++]); } } return 0; } void usage(const char *p) { printf("Usage: %s [-i infile] [-a] [-o outfile] [-v] [-h] [file]/n", p); }
执行结果:
$ ./mygetopt file1 -i infile -a -o outfile -v -h file2
option i: infile
optind=4
option a :a
optind=5
option o: outfile
optind=7
option v: v
optind=8
Usage: ./mygetopt [-i infile] [-a] [-o outfile] [-v] [-h] [file]
optind=9
non-option arguments below:
file1
file2