将多个参数传递给一个选项时 argv 的 getopt 顺序
getopt order of argv when passing multiple arguments to one option
我正在尝试将多个参数传递给一个选项。
例如,
(1) ./someProgram -f opt1 opt2 opt3 -j opt -d
.
(2) ./someProgram -f /dir/dir/* -j opt -d
.
我的 getopt_long 设置如下所示。
const char *short_opt = "hp:j:o:f:";
struct option long_opt[] =
{
{"help", no_argument, NULL, 'h'},
{"journal", required_argument, NULL, 'j'},
{"partition", required_argument, NULL, 'p'},
{"output", required_argument, NULL, 'o'},
{"file", required_argument, NULL, 'f'},
{NULL, 0, NULL, 0}
};
我试图简化主要代码,只是为了让它看起来不那么繁琐。
我留下了与 getopt_long 变量交互的部分。
while ((arg = getopt_long(argc, argv, short_opt, long_opt, NULL)) != -1) {
switch (arg) {
case -1:
case 0:
break;
...
case 'j':
if (optarg) {
setSomeVar; //And nothing else, only set var and break.
}
break;
case 'f':
if (optarg) {
index = optind - 1;
while (index < argc) {
nextOpt = strdup(argv[index]);
index++;
if (nextOpt[0] != '-') {
callFunc(nextOpt);
}
else {
break;
}
}
optind = index - 1;
}
else {
fprintf(stderr, "...\n");
exit(EXIT_FAILURE);
}
break;
case ':':
case '?':
fprintf(stderr, "...");
return (EXIT_FAILURE);
default:
fprintf(stderr, "...", argv[0], arg);
return (EXIT_FAILURE);
};
如果我像下面这样调用我的程序,一切都符合预期。
第一次输入
./prog -f /dir/dir/* - (60 files) or ./prog -f file1 file2 file3
info about file1
info about file2
... and so on
如果我会在最后添加另一个选项。
第二个输入
./prog -f file1 file2 file3 file4 -j smth
info about1 file1
action with -j smth. **End.**
我试图在开头列出所有参数,第二个输入如下:
for (int i = 0; i < argc; i++) {
printf("argv[%d] = %s\n", i, argv[i]);
}
并且结果符合预期(对于第二个输入)
-f, file1,file... -j,print
我再次在 'f' 情况下将此 for 循环包含在我的开关中。
使用第二个输入,我看到第 3 个参数是 -j,第 4 个是 j 的选项,只有在那之后才有所有其他文件。
输出就像你已经猜到的那样,
file1, -j, print, file2, file3,file4
我的问题是为什么会这样?或者我应该如何修复它,或者我需要看吗?
我还试图通过查看此处回答的几个类似问题来改进我的代码,但看起来我已经听从了所有建议。
Parsing command line options with multiple arguments [getopt?]
C getopt multiple value
Get several values for the same option [duplicate]
通过在引号中传递所有参数的解决方案对我不起作用,因为用户可能希望重定向来自 ls 的输入,例如,或者传递带有 * 的目录。
谢谢:)
这是关于 man getopt
中的第六段(对于 Gnu 版本,您显然正在使用它):
By default, getopt() permutes the contents of argv as it scans, so that eventually all the nonoptions are at the end. Two other modes are also implemented. If the first character of optstring is '+' or the environment variable POSIXLY_CORRECT is set, then option processing stops as soon as a nonoption argument is encountered. If the first character of optstring is '-', then each nonoption argv-element is handled as if it were the argument of an option with character code 1. (This is used by programs that were written to expect options and other argv-elements in any order and that care about the ordering of the two.) The special argument "--" forces an end of option-scanning regardless of the scanning mode.
我认为您可以使用任何一种非默认模式来使您的代码工作,但为了可移植性,我会选择 Posix 标准模式。
(尽管我实际上鼓励您不要使用非标准的实用程序参数约定。选项应该采用一个参数;如果您想要的话,可以很容易地在列表中重复一个选项。)
我正在尝试将多个参数传递给一个选项。 例如,
(1) ./someProgram -f opt1 opt2 opt3 -j opt -d
.
(2) ./someProgram -f /dir/dir/* -j opt -d
.
我的 getopt_long 设置如下所示。
const char *short_opt = "hp:j:o:f:";
struct option long_opt[] =
{
{"help", no_argument, NULL, 'h'},
{"journal", required_argument, NULL, 'j'},
{"partition", required_argument, NULL, 'p'},
{"output", required_argument, NULL, 'o'},
{"file", required_argument, NULL, 'f'},
{NULL, 0, NULL, 0}
};
我试图简化主要代码,只是为了让它看起来不那么繁琐。 我留下了与 getopt_long 变量交互的部分。
while ((arg = getopt_long(argc, argv, short_opt, long_opt, NULL)) != -1) {
switch (arg) {
case -1:
case 0:
break;
...
case 'j':
if (optarg) {
setSomeVar; //And nothing else, only set var and break.
}
break;
case 'f':
if (optarg) {
index = optind - 1;
while (index < argc) {
nextOpt = strdup(argv[index]);
index++;
if (nextOpt[0] != '-') {
callFunc(nextOpt);
}
else {
break;
}
}
optind = index - 1;
}
else {
fprintf(stderr, "...\n");
exit(EXIT_FAILURE);
}
break;
case ':':
case '?':
fprintf(stderr, "...");
return (EXIT_FAILURE);
default:
fprintf(stderr, "...", argv[0], arg);
return (EXIT_FAILURE);
};
如果我像下面这样调用我的程序,一切都符合预期。
第一次输入
./prog -f /dir/dir/* - (60 files) or ./prog -f file1 file2 file3
info about file1
info about file2
... and so on
如果我会在最后添加另一个选项。
第二个输入
./prog -f file1 file2 file3 file4 -j smth
info about1 file1
action with -j smth. **End.**
我试图在开头列出所有参数,第二个输入如下:
for (int i = 0; i < argc; i++) {
printf("argv[%d] = %s\n", i, argv[i]);
}
并且结果符合预期(对于第二个输入)
-f, file1,file... -j,print
我再次在 'f' 情况下将此 for 循环包含在我的开关中。 使用第二个输入,我看到第 3 个参数是 -j,第 4 个是 j 的选项,只有在那之后才有所有其他文件。 输出就像你已经猜到的那样,
file1, -j, print, file2, file3,file4
我的问题是为什么会这样?或者我应该如何修复它,或者我需要看吗? 我还试图通过查看此处回答的几个类似问题来改进我的代码,但看起来我已经听从了所有建议。
Parsing command line options with multiple arguments [getopt?]
C getopt multiple value
Get several values for the same option [duplicate]
通过在引号中传递所有参数的解决方案对我不起作用,因为用户可能希望重定向来自 ls 的输入,例如,或者传递带有 * 的目录。
谢谢:)
这是关于 man getopt
中的第六段(对于 Gnu 版本,您显然正在使用它):
By default, getopt() permutes the contents of argv as it scans, so that eventually all the nonoptions are at the end. Two other modes are also implemented. If the first character of optstring is '+' or the environment variable POSIXLY_CORRECT is set, then option processing stops as soon as a nonoption argument is encountered. If the first character of optstring is '-', then each nonoption argv-element is handled as if it were the argument of an option with character code 1. (This is used by programs that were written to expect options and other argv-elements in any order and that care about the ordering of the two.) The special argument "--" forces an end of option-scanning regardless of the scanning mode.
我认为您可以使用任何一种非默认模式来使您的代码工作,但为了可移植性,我会选择 Posix 标准模式。
(尽管我实际上鼓励您不要使用非标准的实用程序参数约定。选项应该采用一个参数;如果您想要的话,可以很容易地在列表中重复一个选项。)