(转)getopt_long及其使用

本文介绍Linux环境下使用getopt_long函数解析命令行参数的方法。通过示例程序详细展示了如何定义短选项与长选项,以及如何处理各种输入情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

?? Linux系统下,需要大量的命令行选项,如果自己手动解析他们的话实在是有违软件复用的思想,不过还好,GNU C library留给我们一个解析命令行的接口(X/Open规范),好好使用它可以使你的程序改观不少。

使用getopt_long()需要引入头文件

#include <getopt.h>

???? 现在我们使用一个例子来说明它的使用。

一个应用程序需要如下的短选项和长选项。


????? 短选项?????????????? 长选项?????????????????????????? 作用

????? -h????????????????????? --help?????????????????????????? 输出程序命令行参数说明然后退出
-o filename??????? --output filename????? 给定输出文件名
-v????????????????????? --version?????????????????????? 显示程序当前版本后退后

为了使用getopt_long函数,我们需要先确定两个结构:

1.一个字符串,包括所需要的短选项字符,如果选项后有参数,字符后加一个":"符号。本例中,这个字符串应该为"ho:v"。(因为-o后面有参 数filename,所以字符后面要加":")

2.一个包含长选项字符串的结构体数组,每一个结构体包含4个域,第一个域为长选项字符串,第二个域是一个标识,只能为0或1,分别代表没有、有。 第三个域永远为NULL。第四个域为对应的短选项字符串。结构体数组的最后一个元素全部为NULL和0,标识结束。在本例中,它应该像一下的样子:

???? const struct option long_options[] = {
{ "help",??????? 0, NULL, 'h' },
{ "output",????? 1, NULL, 'o' },
{ "version", 0, NULL, 'v' },
{ NULL,????????? 0, NULL, 0}
};

调用时需要把main的两个参数argc和argv以及上述两个数据结构传给getopt_long。
每次调用getopt_long,它会解析一个符号,返回相应的短选项字符,如果解析完毕返回-1。所以需要使用一个循环来处理所有的参数,而相应的循环 里会使用switch语句进行选择。如果getopt_long遇到一个无效的选项字符,它会打印一个错误消息并且返回'?',很多程序会打印出帮助信息 并且中止运行;当getopt_long解析到一个长选项并且发现后面没有参数则返回':',表示缺乏参数。当处理一个参数时,全局变量optarg指向 下一个要处理的变量。当getopt_long处理完所有的选项后,全局变量optind指向第一个未知的选项索引。

这一个例子代码为下:

//编译使用gcc -o getopt_long getopt_long.c
#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>

/*程序的名字*/
const char* program_name;

/* 打印程序参数 */
void print_usage (FILE* stream, int exit_code)
{
fprintf (stream, "Usage: %s options [ inputfile ... ]\n", program_name);
fprintf (stream, " -h --help?????????????????????? 显示这个帮助信息.\n"
" -o --output filename 将输出定位到文件.\n"
" -v --version????????????????? 打印版本信息.\n");
exit (exit_code);
}


/* 主程序 */
int main (int argc, char* argv[])
{
int next_option;//下一个要处理的参数符号
int haveargv = 0;//是否有我们要的正确参数,一个标识

/* 包含短选项字符的字符串,注意这里的‘:’ */

const char* const short_options = "ho:v";

/* 标识长选项和对应的短选项的数组 */

const struct option long_options[] = {
{ "help",??????? 0, NULL, 'h' },
{ "output",????? 1, NULL, 'o' },
{ "version", 0, NULL, 'v' },
{ NULL,???????? 0, NULL, 0???? }};//最后一个元素标识为NULL

/* 此参数用于承放指定的参数,默认为空 */
const char* output_filename = NULL;
/* 一个标志,是否显示版本号 */
int verbose = 0;

/* argv[0]始终指向可执行的文件文件名 */

program_name = argv[0];

do
{
next_option = getopt_long (argc, argv, short_options, long_options, NULL);
switch (next_option)
{
case 'h':???? /* -h or --help */????
haveargv = 1;
print_usage (stdout, 0);
case 'o':???? /* -o or --output */
/* 此时optarg指向--output后的filename */
output_filename = optarg;
haveargv = 1;
break;
case 'v':???? /* -v or??? --version */
verbose = 1;
haveargv = 1;
break;
case ':':???? /* 缺乏长选项内容 */
break;
case '?':???? /* 出现一个未指定的参数*/
print_usage (stderr, 1);
case -1:????? /* 处理完毕后返回-1 */
if (!haveargv)
{
print_usage (stderr, 1);
}
break;
default:????? /* 未指定的参数出现,出错处理 */
print_usage (stderr, 1);
break;
}
}while (next_option !=-1);

if (verbose)
{
int i;
for (i = optind; i < argc; ++i)
printf ("Argument: %s\n", argv[i]);
}???????????????????????????

return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值