【发布时间】:2015-08-06 17:49:58
【问题描述】:
我正在尝试创建一个小型 linux 命令行应用程序。 在调用应用程序时可以通过传递参数来运行应用程序,我使用 getopt() 对其进行解析。
可以选择以交互模式运行此应用程序,在这种情况下会显示一个小菜单,并且用户应该能够输入与他们在运行应用程序时添加的选项类似的选项。
为避免在交互模式下创建不同的解析器,我想将键盘输入解析为 argc 和 argv 并将其提供给同一个 getopt() 函数。
我创建的概念证明c 函数如下:
void menuDlg()
{
char kbinput[256];
wordexp_t we;
char **argAr;
int argCount = 0 ,i,er=0;
printf("showing menu options\n");
//...
//...
///grab keyboard input
fgets(kbinput,256,stdin);
///the "\n" in kbinput breaks we
///and we.we_wordc return weird value,
///so we need to remove it
for (i=0; i<256; i++)
{
if (kbinput[i]=='\n')
{
kbinput[i]='\0';
break;
}
}
printf("you typed |%s|\n",kbinput);
we.we_offs = 0;
if ( (er=wordexp(kbinput, &we, 0)) != 0)
{
printf("error in word expansion %d\n",er);
}
argAr = we.we_wordv;
argCount = we.we_wordc;
printf("we.c=%u\n",we.we_wordc);
main_dialog( argCount, argAr );
wordfree(&we);
}
是 main_dialog() 解析 cli 选项
void main_dialog( int argc, char* argv[] )
{
while ( (ch = getopt_long(argc, argv, "yscvh", longopts, NULL)) != -1 )
switch (ch)
{
...
}
}
但是当我运行这个时,我的应用程序在调用 getopt_long() 时崩溃了。
我读到argv 的最终条目应该是null。所以对于参数 "foo bar" ,我们有 argc=2 ,但是 argv[0]="foo" , argv[1]="bar" 和 argv[2]='\0' 。在wordexp documentation 中几乎没有说明 we_wordv 的内部结构(即关于尾随 NULL 数组条目),所以我不知道这是否是问题所在。
这可能是问题的根源吗?是否还有另一个 glib 函数可以满足我的需求?
谢谢
【问题讨论】:
-
首先,
getopt和getopt_long期望实际参数从argv[1]开始。其次,终止条目是argv[argc],它是一个空指针,即NULL,wordexp为您添加。 -
还有,当crash发生时,
argc的值和argv的内容是什么? -
您之前是否使用过
getopt()或getopt_long()?如果是这样,您可能需要重新初始化它们,以便它们从当前参数列表的开头开始,而不是继续使用原始参数列表。如何进行重置并不总是很清楚。 BSD (Mac OS X) 文档:为了使用getopt()计算多组参数,或多次计算一组参数,变量optreset必须在第二个之前设置为1,并且对getopt()的每组额外调用,以及变量optind都必须重新初始化。 其他人则不需要。 -
@JonathanLeffler 宾果游戏!通读手册,它出现在 linux 中重置 getopt() 子系统必须通过
optind=0;仍然让我走在正确的轨道上。您可能想将此添加为答案!