getopt值保持为空

9

我正在传递程序输入,我可以在argv中看到它们,但getopt似乎没有我期望的参数。

这是我运行程序的方式:./my_prog -X -f filename

<snip>
while ((opt = getopt(argc, argv, "Xf:eE:dD")) != EOF) {
    switch (opt) {
       case 'X':
       case 'f':
                if (optarg == NULL)
                fput("no point of living", fp);         << for debugging

</snip>

我总是得到空的optarg。为什么?


你是在看到 -X 还是 -f 的调试信息? - mu is too short
你确定是 -f 而不是来自 -X 的穿透吗? - mu is too short
在“-X”上,我不想做任何事情。能够顺延到“-f”并捕获文件名吗? - hari
2
如果你不想在“-X”上做任何事情,那么就在它的“case”后面放一个“break”。 - mu is too short
4个回答

12

你的参数字符串中X后面没有冒号(例如X:f),因此optarg将始终为null。

我还要指出,在switch语句中,通常在每个case后面需要加上break(通常情况下是这样,但不总是这样,但处理参数时通常需要这样做), 所以:

switch ( ... ) {
    case 'X': {
        // do something
    } break;

    case 'f': {
        // do something else
    } break;
}

-f 参数不应该是 optarg 吗? - hari
我有“Xf”,而不是“X:f”,因此“-X”的optarg将始终为NULL,但为什么“-f”的optarg也是NULL??这是因为我没有在X之后中断吗? - hari
根据您的代码,当评估opt =='f'时,我预计optarg不会为NULL。它应该是“filename” 。也许可以发布更多代码? - par
@hari 你是说当你以 ./my_prog -X -f filename 的方式运行它时,它会打印两次“no point of living”吗?如果是这样的话,那么肯定有其他问题存在,请发布一个完整可编译示例的代码,以展示这种行为。 - nos
@nos 不对。对于“-f”,它打印出“没有生存的意义”,这是错误的,据我所知。optarg 应该是“文件名”。对于“-f”,optarg 不应该为空。 - hari
我只是在“X”之后不得不中断。感谢大家。 - hari

3

我刚刚处理了这个问题,似乎这个问题从未被完全回答。

在调用getopt之前,你必须确保设置外部libc变量opterr = 0;如果你没有重置它,并且getopt以前在系统中的任何其他应用程序中出现过错误,它将无法处理参数。我还要重申一个现有观点,在case 'X'后没有break语句是一个明显的问题,因为它会落空。

getopt每次只处理一个参数,所以从X的情况落入f的情况是不好的。除非你绝对确定它应该落空(这在我的经验中非常罕见),否则你应该在每个switch的case语句中都有一个break。作为另一个好习惯,除非它是一个return语句或break或者通过函数或方法调用进入新范围,否则你应该总是用{ }包括代码块(参考你的条件语句)。

我认为你的选项字符串Xf:eE:dD很好。这表示:

1)以下内容只是选项标志,始终没有参数:XedD

2)以下选项将需要参数:fE

如果这是你要查找的功能,给定的选项字符串就很好。如果你使用GNU libc,可以像上面其他答案中所述,在选项字符串后面使用::来表示该选项可能具有参数,但不一定有。

因此,请确保在文件顶部至少有:

extern int opterr;

在您的代码中第一次调用getopt之前,将opterr设置为0。

例如:

opterr = 0;

while ((opt = getopt(argc, argv, "Xf:eE:dD")) != EOF) {
    switch (opt) {
       case 'X':
       case 'f':
                if (optarg == NULL)
                fput("no point of living", fp);         << for debugging

这至少能部分解决你的问题。这里有一个示例链接:http://www.gnu.org/software/libc/manual/html_node/Example-of-Getopt.html。祝好,Jon

谢谢您发布这篇文章。我一直在为我的代码苦苦挣扎,而opterr=0解决了我的问题。 - user4650542
很高兴这对你有所帮助。我还记得很久以前我也遇到过这个问题,整个过程让我疯狂了数小时。 - jhyry

2
对于其他访问此页面的人: 来自http://www.gnu.org/software/libc/manual/html_node/Using-Getopt.html#Using-Getopt此字符串中的选项字符后面可以跟随冒号(“:”)表示它需要一个必需参数。如果选项字符后面跟随两个冒号(“::”),则其参数是可选的;这是GNU扩展。

因此,在您的参数中,您可能会使用:"X:f:e:E:d:D:"

我也遇到了同样的问题。


0

我知道这篇文章有点老了,但最近我发现 getopt 的使用行为似乎有所改变。也许是不同的环境造成的差异,但今天使用它时,需要在标记后面直接跟上 optarg(没有空格),否则 optarg 为空。

使用您的示例,将 ./my_prog -X -f filename 替换为 ./my_prog -X -ffilename

虽然感觉有些奇怪,但我发现这样可以正常工作。希望可以帮助其他人。请确保两种方式都尝试一下。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接