一、前言
在Linux下开发时,命令行的使用是必不可少的,经常会在命令行运行各种命令,启动服务,启动应用程序,查看函数用法等等;运行这些命令时都会传入一些参数,比如:
$ ./c_app 127.0.0.1 8888 小明
$ man printf
这些命令行参数解析,Linux提供了一套函数,可以很方便的解析传入的各种参数信息。
这篇文章就介绍如何使用Linux提供的解析函数,完成命令的行的参数解析。
函数原型如下:
#include <unistd.h>
#include <getopt.h>
这3个是全局变量
extern char *optarg;
extern int optind, opterr, optopt;
功能介绍:
optarg——指向当前选项参数(如果有)的指针。 比如: cp 123.c 888/ -fv 、 gcc 123.c -o app
optind——再次调用 getopt() 时的下一个 argv 指针的索引。
optopt——最后一个已知选项。
int getopt(int argc, char * const argv[],const char *optstring);
函数功能: 解析短选项形参. 只能解析单个字符.
函数参数:
int argc 就是main函数传入的argc
char * const argv[] 就是main函数传入的argv
const char *optstring 将要解析的选项形参格式.
比如: "a:b:c:v" 字母后面跟着冒号就表示该选项形参必须传递参数.
传入形参的时候: a.out -a 666 -b 777 -c 888 -v
返回值:
解析成功就返回当前解析的选项形参的字符. 并且会给全局变量赋值. optarg这个指针就会指向该选项形参后面的数据地址.
如果失败就返回-1 解析错误会返回?
int getopt_long(int argc, char * const argv[],
const char *optstring,
const struct option *longopts, int *longindex);
函数功能:解析长选项形参.
struct option {
const char *name; 表示要解析的长选项字符串 --abc
int has_arg; 0表示不需要参数 1表示必须要 2表示可选
int *flag; 一般NULL
int val; 当解析到正确的长选项形参的时返回的字符 k
};
int getopt_long_only(int argc, char * const argv[],
const char *optstring,
const struct option *longopts, int *longindex);
函数功能:同时支持解析长选项形参和短选项形参.
二、案例代码
2.1 解析命令行的短选项形参
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
int main(int argc,char **argv)
{
int c;
while(1)
{
//解析传入的选项参数 ./a.out -a 123 -b 456 -c 789 -v
c=getopt(argc,argv,"a:b:c:v?");
if(c==-1)break;
switch(c)
{
case 'a':
printf("当前的选项形参:a,值:%s\n",optarg);
break;
case 'b':
printf("当前的选项形参:b,值:%s\n",optarg);
break;
case 'c':
printf("当前的选项形参:c,值:%s\n",optarg);
break;
case 'v':
printf("当前版本:1.2.3\n");
break;
case '?':
printf("用法:./a.out [-a 123 -b 456 -c 789 -v] \n");
break;
default:
break;
}
}
return 0;
}
[wbyq@wbyq linux_c]$ ./a.out -a 123 -b 67 -c 999
当前的选项形参:a,值:123
当前的选项形参:b,值:67
当前的选项形参:c,值:999
[wbyq@wbyq linux_c]$ ./a.out -a
./a.out: option requires an argument -- 'a'
用法:./a.out [-a 123 -b 456 -c 789 -v]
[wbyq@wbyq linux_c]$ ./a.out -?
用法:./a.out [-a 123 -b 456 -c 789 -v]
[wbyq@wbyq linux_c]$ ./a.out -v
当前版本:1.2.3
[wbyq@wbyq linux_c]$
2.2 解析命令行的长选项形参
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
struct option opt_list[]=
{
{"a123",1,NULL,'a'},
{"b123",1,NULL,'b'},
{"c123",1,NULL,'c'},
{"help",0,NULL,'?'},
};
int main(int argc,char **argv)
{
int c;
while(1)
{
//解析传入的选项参数 ./a.out -a 123 -b 456 -c 789 -v
c=getopt_long(argc,argv,"a:b:c:v?",opt_list,NULL);
if(c==-1)break;
switch(c)
{
case 'a':
printf("当前的选项形参:a,值:%s\n",optarg);
break;
case 'b':
printf("当前的选项形参:b,值:%s\n",optarg);
break;
case 'c':
printf("当前的选项形参:c,值:%s\n",optarg);
break;
case 'v':
printf("当前版本:1.2.3\n");
break;
case '?':
printf("用法:./a.out [-a 123 -b 456 -c 789 -v] \n");
break;
default:
break;
}
}
return 0;
}
[wbyq@wbyq linux_c]$ ./a.out -a 12345
当前的选项形参:a,值:12345
[wbyq@wbyq linux_c]$ ./a.out --a123 12345
当前的选项形参:a,值:12345
[wbyq@wbyq linux_c]$ ./a.out -?
用法:./a.out [-a 123 -b 456 -c 789 -v]
[wbyq@wbyq linux_c]$ ./a.out --help
用法:./a.out [-a 123 -b 456 -c 789 -v]
[wbyq@wbyq linux_c]$
2.3 解析复杂的命令行选项形参
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
struct option opt_list[]=
{
{"a123",1,NULL,'a'},
{"b123",1,NULL,'b'},
{"c123",1,NULL,'c'},
{"help",0,NULL,'?'},
};
int main(int argc,char **argv)
{
int c;
while(1)
{
//解析传入的选项参数 ./a.out -a 123 -b 456 -c 789 -v
c=getopt_long_only(argc,argv,"a:b:c:v?",opt_list,NULL);
if(c==-1)break;
switch(c)
{
case 'a':
printf("当前的选项形参:a,值:%s\n",optarg);
break;
case 'b':
printf("当前的选项形参:b,值:%s\n",optarg);
break;
case 'c':
printf("当前的选项形参:c,值:%s\n",optarg);
break;
case 'v':
printf("当前版本:1.2.3\n");
break;
case '?':
printf("用法:./a.out [-a 123 -b 456 -c 789 -v] \n");
break;
default:
break;
}
}
return 0;
}
[wbyq@wbyq linux_c]$ ./a.out
[wbyq@wbyq linux_c]$ ./a.out -a 1234
当前的选项形参:a,值:1234
[wbyq@wbyq linux_c]$ ./a.out -a123 1234
当前的选项形参:a,值:1234
[wbyq@wbyq linux_c]$ ./a.out --a123 1234
当前的选项形参:a,值:1234