[英]Passing command line arguments to different parts of my program in ANSI C
我试图阅读有关该主题的内容,但是当我尝试运行我认为正确的东西时,它并没有完成我想要的事情:)
我有一个主程序,该程序应带有三个强制性参数,我们称它们为t, p and s
。 然后,我有几个模块,作为其初始化的一部分,它们也依赖于命令行参数。 这些模块有一个命令行自变量,表明将要使用它们。
当我在主程序中构建可能的命令行选项字符串时,它看起来像t:p:s:
并且我还循环了所有模块并请求它们的“触发”选项字符。 因此,完成的字符串可能看起来像t:p:s:iv
,其中i
和v
是两个不同模块的触发器。
然后在while循环中,我做类似的事情(选项是上述字符串)
while ((opt = getopt(argc, argv, options)) != -1) {
switch (opt) {
case 't':
break;
case 's':
break;
case 'p':
break;
case 'h':
default:
ShowHelp(this, argc, argv);
exit(EXIT_FAILURE);
}
/*
* Check all available modules and see if options should be passed to it
*/
i = 0;
while((module = this->availablemodules[i++]) != NULL) {
if(opt == module->triggerArg) {
output = module->ParseOptions(module, argc, argv);
AddActiveModule(this, module);
}
}
}
this->availablemodules
变量是指向现有模块的NULL终止指针数组。 如您所见,我首先检查主程序使用的选项,然后检查给定的选项是否是模块的触发选项,在这种情况下,我将发送该模块要解析的参数。
然后,该模块可能会使用不同的选项集。 所以输入的参数可能看起来像这样
./myprog -t foo -s bar -p 10 -i -c 2 -v -c 1 -t bar
其中-i
和-v
是模块“触发器”,其后的选项应在该模块解析功能中处理。
我如何最好地完成这项工作? 我如何最好地处理这样一个事实:模块触发的选择可能是一样的(由主要程序所需的选项之一,即t:
既用作主程序一个选项, t
作为一个模块“触发”)? 是否可以强制某些命令为强制性命令,或者在解析所有选项后是否必须手动检查该命令?
首先,我使用每个模块的optionstring构造了主程序optionstring,但是如果不调用一个模块,则会使系统感到困惑。
我希望一切都清楚了,但如果不仅仅是问...我对此应该如何处理有些困惑,因此可能无法很好地解释它。
更新:我只是读了一些有关getopt_long的内容,并在想,是否有可能这样做
./myprog -t foo -s bar -p 10 --module=module1 -c 2 --module=module2 -c 1 -t bar
并且让module1
和module2
是什么来标识要激活的模块? 还是会让解析器多次使用--module
?
一种方法是将参数的引号括在引号中:
./myprog -t foo -s bar -p 10 -i="-c 2" -v="-c1 -t bar"
然后将引用的参数传递给模块。 这使您可以在每个模块的有效参数集中重复参数标识符。
或者,使用.ini文件:
[global]
t=foo
s=bar
p=10
[i]
c=2
[v]
c1=true
t=bar
并将其作为唯一参数传递给应用程序。 有很多库可以解析这种文件(我认为它甚至是Win32 API的一部分)。
.ini文件的替代方案是.xml格式,但解析起来更复杂,但是您可以使用模式来验证文件。 同样,有些库可以为您做到这一点。
正如我在最初的更新中所述,我做了。 现在,我传递--module=nameofModule
然后传递该模块的所有选项。 当识别到--module
选项时,我停止在常规while循环中评估这些选项,而是将所有以下所有选项放在新数组中,以传递给指定模块的parseOptions
函数。 我一直这样做,直到找到新的--module
选项或EOF
为止。 如建议的那样,我不对--module
选项使用可打印的字符,因为如果现有选项具有相同的字符,则可能会混淆解析算法,而我使用字符0x07f (DEL)
。
struct option long_options[] = {
{ "module", required_argument, &long_val, 0x7f },
{ "src", required_argument, &long_val, 's' },
{ "dst", required_argument, &long_val, 'd' },
{ 0, 0, 0, 0 } /* terminating -0 item */
};
我的解析选项循环看起来像这样
// Hold pointer to a module activated by being declared in the arguments
module* found_module = NULL;
// Hold options to pass to module
char* module_options[256];
int module_argc = 0;
int arg_index = 0;
while ((opt = getopt_long(argc, argv, "-0x7fsd", long_options, &long_opt_index)) != EOF) {
++arg_index;
/*
* If we have found a module declaration store all following options until EOF or a new
* module is declared to be sent to the modules argument parsing function
*/
if(found_module && long_val != 0x7f) {
strcpy(module_options[module_argc], argv[arg_index]);
++module_argc;
}
else {
if(found_module) {
output = found_module->ParseOptions(found_module, module_argc, module_options);
fprintf(stderr, "Adding module %s as active!\n", found_module->name);
AddActiveModule(this, found_module);
found_module = NULL;
module_argc = 0;
// todo: also empty the module_options array
}
switch (opt) {
case 0: /* this is returned for long options with option[i].flag set (not NULL).
the flag itself will point out the option recognized, and long_opt_index is now relevant */
switch(long_val)
{
case 0x7f:
printf("Option --module, Argument: %s.\n", long_opt_index, optarg);
i = 0;
while((module = this->availablemodules[i++]) != NULL) {
if(strcmp(optarg, module->optmoduleName)) {
found_module = module;
continue;
}
}
break;
/* there's no default here */
}
break;
case 'h':
default:
ShowHelp(this, argc, argv);
exit(EXIT_FAILURE);
} // switch
} // else
} // while
/*
* Have a trailing check here since EOF will terminate while loop but we might have a
* module left to activate
*/
if(found_module) {
output = found_module->ParseOptions(found_module, module_argc, module_options);
fprintf(stderr, "Adding module %s as active!\n", found_module->name);
AddActiveModule(this, found_module);
found_module = NULL;
}
这似乎很完美,但是我可能还是错过了一些东西。 如前所述,我有点对getopt和似乎能够进行的自动重新排序感到困惑。 当我收集-
选项字符串开头的-
可以防止这种情况,对吗?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.