getopt立即退出循环

时间:2014-09-18 22:42:25

标签: c getopt

我试图让getopt与我的C程序一起工作,但我发现它不起作用。 这是不起作用的功能

char* getFlagArg(int argc, char **argv, char flag) {
 extern char *optarg;
 extern int optind, optopt, opterr;
 char opt;
 char options[3] = {flag,':',0};
 while((opt = getopt(argc, argv, options)) != -1) {
     if(opt == flag)
         return optarg;
 }
 return "";
}

当我运行此代码时,它会立即退出循环(循环甚至不会运行一次)。我无法弄清楚为什么会这样。我已经验证了argc,argv和选项都是我所期望的。思考?拜托,谢谢!

2 个答案:

答案 0 :(得分:1)

我在问题的评论中试图提出的观点是:

char *arg;

arg = getFlagArg (argc, argv, 'b');
printf ("-b arg = %s\n", arg);
arg = getFlagArg (argc, argv, 'u');
printf ("-u arg = %s\n", arg);

如果您已经拨打getFlagArggetopt,则第二次通话可能会失败。想象一下,您有一个接受参数的选项-b,命令行为./a.out -u foo -b quux filename。由于您首先搜索了-b,因此optind将为5,并且搜索-u将失败,因为optind大于1,这是值optind必须在我提供的示例命令行中找到-u选项。

你需要"重置"将getopt设置为1 optind。当然,如果这不是问题,我们需要查看调用getFlagArg的代码。

修改

允许不带参数的选项位于同一个argv元素中。 getopt可以处理此问题,但如果您有两个选项-a-c,则./a.out -cau foo将与getopt一起使用,但您无法找到-c找到-a之后,即使再次将optind设置为1也是如此。只有在您通过-u foo(或任何其他需要参数的选项)之后,您才能重置optind并重新开始解析。

FreeBSD以及可能的其他一些BSD克隆提供了一个非标准的optreset变量来处理这种情况。但是,Linux上的Glibc没有,所以要小心这个奇怪的" quirk" getopt

答案 1 :(得分:0)

这应该是int opt而不是char c,因为它是getopt()返回的整数值。您没有提供您使用的C版本;因此很难进行测试以验证您获得的行为,但假设从intchar然后再转回int的转换使其等于{{1在这种情况下。

当然,如果更改-1的声明,您还应该使用适当的转换来更改代码,并使用flag的值进行比较。