一. 前言
当我们编写好一个应用程序,经常需要添加一些命令行选项以支持不同的场景。假设我们编写了一个可以以指定方式连接到其他主机端口的应用程序 connect,我们可以执行 ./connect -m tcp -s 192.168.1.105 -p 8888 表示要以 tcp 方式连接到主机名为 192.168.1.105 的 8888 端口,这样你的程序不会被写死,当你需要连接到其他主机端口的时候才不用重新编译程序。那么不可避免的,在程序中就要有相应的解析命令行参数的功能代码,才能知道 -m 后面要解释成 tcp/udp,-s 后面要解析成 IP 地址,-p 后面要解析成端口名,getopt 函数正是用来帮助我们解析命令行参数选项的。
二. 用法
所需头文件 :#include <unistd.h>
函数原型 :int getopt(int argc, char * const argv[], const char * optstring);
参数说明
argc,argv :调用 main 函数时传入的参数。
optstring :指定合法的选项。一个字符代表一个选项,如前言中的 -m,-s,-p。当我们需要表示该选项后面还有带参数时,需要在该字符后面添加一个冒号 : ,所以如果要支持前言中的选项解析,optstring 可以写成"m:s:p:",如果该选项后面明确不带参数,那么直接在 optstring 中添加该选项对应的字符即可;如果 optstring 中某个字符后带两个冒号表示该字符对应的选项带可选参数(参数可有可无),若有参数,optarg 指向该该参数,否则 optarg 为0。(optarg 的含义见下面)
函数相关的全局变量
optarg :optarg 是一个 char * 指针,指向当前选项的参数(如果该选项有参数的话)。
optind :一个 int 类型的数,表示当前解析的选项在 argv 的索引值。初始值为 1,最大值为 argc - 1。
opterr :一个 int 类型的数,opterr 非零表示产生的错误要输出到标准错误,初始值为 1。
optopt :一个 int 类型的数,当发现无效选项字符时,getopt() 函数或返回字符 '?' 或返回字符 ':',此时 optopt 包含了所发现的无效选项字符。
返回值说明
-1 : 表示 argv 中的参数列表已经解析完毕。
0 :表示成功解析该选项。
'?' :如果函数遇到一个非 optstring 指定的字符选项则返回 '?' ,表示该选项是未指定被解析的,并且将该选项存放到全局变量optopt 中。
三. 案例
拿前言中的应用程序 connect 为例,我们要解析三个选项,-m 指定以 tcp/udp 连接,-s 指定 IP 地址,-p 指定端口号,解析参数选项的代码如下。
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#define MODE_MAX_LEN 4
#define IP_MAX_LEN 16
int main(int argc, char * argv[])
{
int i;
int ch;
char mode[MODE_MAX_LEN] = {0};
char ip_addr[IP_MAX_LEN] = {0};
int port = 0;
printf("测试getopt函数的程序\n");
while ((ch = getopt(argc, argv, "m:s:p:")) != -1)
{
switch (ch)
{
case 'm':
{
snprintf(mode,"%s",optarg,strlen(optarg));
printf("模式:%s\n",mode);
break;
}
case 's':
{
snprintf(ip_addr,"%s",optarg,strlen(optarg));
printf("IP地址:%s\n",ip_addr);
break;
}
case 'p':
{
port = atoi(optarg);
printf("端口号:%d",port);
break;
}
}
}
return 0;
}