是否可以使用 getopt_long 来解析类似于 C 程序中的命令行参数的字符串数组?
is it possible to use getopt_long to parse arrays of strings similar to command line arguments in a C program?
我知道应该使用 getopt 来解析命令行参数,而不是字符串。
但是,我感到困惑的是,如果我向它传递一个字符串数组,"looks like" argv 变量,getopt_long 似乎有效,但 只有第一个我称之为的时间。对于第二次和所有后续时间,我称之为它忽略任何参数和 returns 默认参数。
我这样做的原因是我正在将一个应用程序转换为一个 "interactive" 版本的命令行参数,它要求用户提供一些参数,然后根据这些参数执行一些操作争论,然后要求更多的争论等等。
以下代码是重现错误的最小示例
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
struct input_parameters{
char * d; // data set
};
int solver_help(int argc, char* const argv[], struct input_parameters * p)
{
int c;
p->d = "default name";
while (1)
{
static struct option long_options[] =
{
{"data", required_argument, 0, 'd'},
{0, 0, 0, 0}
};
/* getopt_long stores the option index here. */
int option_index = 0;
c = getopt_long (argc, argv, "d:",
long_options, &option_index);
/* Detect the end of the options. */
if (c == -1)
break;
switch (c)
{
case 'd': p->d = optarg;
break;
default:
printf("wrong option specification\n");
exit(-1);
}
}
return 0 ;
}
int main () {
int argc_first = 3;
char * const argv_first[] = { "getopt_test", "--data", "first" };
struct input_parameters first_input;
solver_help(argc_first, argv_first, &first_input);
printf("I think the data is: %s\n", first_input.d);
int argc_second = 3;
char * const argv_second[] = { "getopt_test","--data", "second" };
struct input_parameters second_input;
solver_help(argc_second, argv_second, &second_input);
printf("I think the data is: %s\n", second_input.d);
return 0;
}
这段代码的输出是
I think the data is: first
I think the data is: default name
来自 getopt
的手册页:
In order to use getopt()
to evaluate multiple sets of arguments, or
to evaluate a single set of arguments multiple times, the variable
optreset
must be set to 1
before the second and each additional
set of calls to getopt()
, and the variable optind
must be
reinitialized.
稍微修改您的代码即可获得所需的结果:
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
struct input_parameters {
char * d; // data set
};
int solver_help(int argc, char* const argv[], struct input_parameters * p)
{
p->d = "default name";
static struct option long_options[] =
{
{"data", required_argument, 0, 'd'},
{0, 0, 0, 0}
};
int option_index = 0;
optreset = 1; /* ADD THIS */
optind = 1; /* ADD THIS */
int c = getopt_long(argc, argv, "d:",
long_options, &option_index);
switch ( c )
{
case -1:
break;
case 'd':
p->d = optarg;
break;
default:
printf("in default case...\n");
printf("wrong option specification\n");
exit(EXIT_FAILURE);
}
return 0;
}
int main(void) {
int argc_first = 3;
char * const argv_first[] = { "getopt_test", "--data", "first" };
struct input_parameters first_input;
solver_help(argc_first, argv_first, &first_input);
printf("I think the data is: %s\n", first_input.d);
int argc_second = 3;
char * const argv_second[] = { "getopt_test","--data", "second" };
struct input_parameters second_input;
solver_help(argc_second, argv_second, &second_input);
printf("I think the data is: %s\n", second_input.d);
return 0;
}
输出:
paul@horus:~/src/sandbox$ ./go
I think the data is: first
I think the data is: second
paul@horus:~/src/sandbox$
我知道应该使用 getopt 来解析命令行参数,而不是字符串。
但是,我感到困惑的是,如果我向它传递一个字符串数组,"looks like" argv 变量,getopt_long 似乎有效,但 只有第一个我称之为的时间。对于第二次和所有后续时间,我称之为它忽略任何参数和 returns 默认参数。
我这样做的原因是我正在将一个应用程序转换为一个 "interactive" 版本的命令行参数,它要求用户提供一些参数,然后根据这些参数执行一些操作争论,然后要求更多的争论等等。
以下代码是重现错误的最小示例
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
struct input_parameters{
char * d; // data set
};
int solver_help(int argc, char* const argv[], struct input_parameters * p)
{
int c;
p->d = "default name";
while (1)
{
static struct option long_options[] =
{
{"data", required_argument, 0, 'd'},
{0, 0, 0, 0}
};
/* getopt_long stores the option index here. */
int option_index = 0;
c = getopt_long (argc, argv, "d:",
long_options, &option_index);
/* Detect the end of the options. */
if (c == -1)
break;
switch (c)
{
case 'd': p->d = optarg;
break;
default:
printf("wrong option specification\n");
exit(-1);
}
}
return 0 ;
}
int main () {
int argc_first = 3;
char * const argv_first[] = { "getopt_test", "--data", "first" };
struct input_parameters first_input;
solver_help(argc_first, argv_first, &first_input);
printf("I think the data is: %s\n", first_input.d);
int argc_second = 3;
char * const argv_second[] = { "getopt_test","--data", "second" };
struct input_parameters second_input;
solver_help(argc_second, argv_second, &second_input);
printf("I think the data is: %s\n", second_input.d);
return 0;
}
这段代码的输出是
I think the data is: first
I think the data is: default name
来自 getopt
的手册页:
In order to use
getopt()
to evaluate multiple sets of arguments, or to evaluate a single set of arguments multiple times, the variableoptreset
must be set to1
before the second and each additional set of calls togetopt()
, and the variableoptind
must be reinitialized.
稍微修改您的代码即可获得所需的结果:
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
struct input_parameters {
char * d; // data set
};
int solver_help(int argc, char* const argv[], struct input_parameters * p)
{
p->d = "default name";
static struct option long_options[] =
{
{"data", required_argument, 0, 'd'},
{0, 0, 0, 0}
};
int option_index = 0;
optreset = 1; /* ADD THIS */
optind = 1; /* ADD THIS */
int c = getopt_long(argc, argv, "d:",
long_options, &option_index);
switch ( c )
{
case -1:
break;
case 'd':
p->d = optarg;
break;
default:
printf("in default case...\n");
printf("wrong option specification\n");
exit(EXIT_FAILURE);
}
return 0;
}
int main(void) {
int argc_first = 3;
char * const argv_first[] = { "getopt_test", "--data", "first" };
struct input_parameters first_input;
solver_help(argc_first, argv_first, &first_input);
printf("I think the data is: %s\n", first_input.d);
int argc_second = 3;
char * const argv_second[] = { "getopt_test","--data", "second" };
struct input_parameters second_input;
solver_help(argc_second, argv_second, &second_input);
printf("I think the data is: %s\n", second_input.d);
return 0;
}
输出:
paul@horus:~/src/sandbox$ ./go
I think the data is: first
I think the data is: second
paul@horus:~/src/sandbox$