【问题标题】:getopt() doesn't return the next argumentgetopt() 不返回下一个参数
【发布时间】:2019-11-26 05:22:40
【问题描述】:

看看这段代码:-

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char *argv[]){
    char ch;
    int value;
    while((ch = getopt(argc, argv, "n: o"))!=EOF){
        switch(ch){
            case 'n':
                value = atoi(optarg);
                fprintf(stdout,"\nParameter n");
                //Do something
                break;
            case 'o':
                fprintf(stdout,"\nParameter 0");
                //Do something
                break;
            default:
                fprintf(stdout,"\nInvalid!");
        }
        argc -= optind;
        argv += optind;
    }
}

当我传递以下参数时

./program -n 123 -o

我得到了这个结果

Parameter n

虽然我希望得到这个

Parameter n
Parameter o

为什么 getopt() 在循环的第二次迭代中不返回下一个参数?

更新

所以代码应该是这样的:-

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char *argv[]){
    char ch;
    int value;
    while((ch = getopt(argc, argv, "n:o"))!=-1){
        switch(ch){
            case 'n':
                value = atoi(optarg);
                fprintf(stdout,"Parameter n (%d)\n", value);
                //Do something
                break;
            case 'o':
                fprintf(stdout,"Parameter o\n");
                //Do something
                break;
            default:
                fprintf(stdout,"Invalid!\n");
                break;
        }
    }
}

【问题讨论】:

    标签: c getopt


    【解决方案1】:

    主要问题

    在循环中,你有:

        argc -= optind;
        argv += optind;
    

    那是一场灾难——不要这样做。您可以在循环完成后(一次)使用这些语句,但不能在循环体中使用。它强制代码跳过选项;在严重的情况下,它最终可能会尝试解析空指针或环境,这两者都不太可能有帮助(并且两者都是未定义的行为,因此 YMMV)。

    切题

    请注意,您已指定空白是选项之一。因此有人可以写:

    ./a.out -' ' -n 123 -o
    

    并且空白将被视为标志选项(如-o)。这可能不是你的想法。使用"n:o",其中不包含空格。

    你打印:

    fprintf(stdout,"\nParameter 0");
    

    该声明的三个小问题:

    1. 0 应该是 o — 它们是不同的。
    2. 将换行符放在输出格式的末尾而不是开头(除非您想要双倍行距)。请注意,在打印换行符之前可能不会生成输出,因此末尾的换行符可确保打印的数据更及时地出现。
    3. 习惯上使用fprintf(stdout, …) 而不是printf(…)。不是完全错误,而是不同寻常。

    getopt() 函数由 POSIX 定义为在完成选项处理时返回 -1 而不是 EOF。这样它在&lt;unistd.h&gt; 中的声明就不会与&lt;stdio.h&gt; 中的EOF 的定义相关联。 (基本原理部分明确指出:getopt() 函数应返回-1,而不是EOF,因此不需要&lt;stdio.h&gt;)一些系统在历史上声明为getopt()&lt;stdio.h&gt; 中,但 POSIX 将它放在 &lt;unistd.h&gt; 中并说它返回 -1

    您应该在开关中的 default: 大小写之后包含一个 break;。这是一种基本的防御性编程措施——即使有人在default: 标签之后添加另一个案例标签,它也能确保不会失败。

    【讨论】:

    • 哇从来没有意识到它有这么多错误。非常感谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-13
    • 2023-03-25
    • 1970-01-01
    相关资源
    最近更新 更多