通用解决方案
解决所提出问题的最简单方法是:
n = atoi(argv[1]);
argv[1] = argv[0];
++argv;
--argc;
while ((opt = getopt(argc, argv, "hi:o:")) != -1)
{
...as before...
}
这有效地消耗了第一个选项,然后将事情重新调整为正统格式。这适用于getopt()
远程符合标准(事实上和法律上)的任何版本。请注意,如果您不重新分配argv[1] = argv[0];
,getopt()
将使用原始值argv[1]
(本示例中的数字)作为“程序名称”。
使用 GNUgetopt()
使用 GNU getopt()
,有两种方法可以解决这个问题。一个使用“按顺序返回”功能,以便将非选项(“文件名”)参数视为以选项字符代码 1(ASCII SOH 控制字符;又名Control-A)为前缀。另一个使用默认模式,从而getopt()
在处理选项时对选项进行置换。请注意,默认情况下这在 Mac OS X 和其他平台上不可用。
这段代码几乎完成了这两项工作;您只需使用"-hi:o:"
.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
int main(int argc, char **argv)
{
int n;
int opt;
char *ifile = 0;
char *ofile = 0;
n = atoi(argv[1]);
while ((opt = getopt(argc, argv, "hi:o:")) != -1)
{
printf("Option: %c\n", opt);
switch (opt)
{
case 'i':
ifile = optarg;
break;
case 'o':
ofile = optarg;
break;
case 'h':
printf("...");
break;
case 1:
n = atoi(optarg);
break;
default:
printf("Invalid Option %d\n", opt);
exit(1);
}
}
printf("argc = %d; optind = %d\n", argc, optind);
for (int i = optind; i < argc; i++)
printf("argv[%d] = %s\n", i, argv[i]);
if (ifile != 0)
printf("i-file: %s\n", ifile);
if (ofile != 0)
printf("o-file: %s\n", ofile);
printf("%d\n", n);
return 0;
}
使用“permute”运行的示例:
$ go9 9 -i in -o out
Option: i
Option: o
argc = 6; optind = 5
argv[5] = 9
i-file: in
o-file: out
9
$
使用“按顺序返回”的示例运行:
$ go9 9 -i in -o out
Option:
Option: i
Option: o
argc = 6; optind = 6
i-file: in
o-file: out
9
$
如果您希望它工作,请确保您没有设置环境变量 POSIXLY_CORRECT。您可以在选项字符串前加上 a+
来强制执行类似 POSIX 的行为。