c++ - getopt 无法检测到选项的缺失参数

标签 c++ c getopt

我有一个接受各种命令行参数的程序。为了简单起见,我们说它需要 3 个标志,-a-b-c,并使用以下代码解析我的论点:

    int c;
    while((c =  getopt(argc, argv, ":a:b:c")) != EOF)
    {
        switch (c)
        {
             case 'a':
                 cout << optarg << endl;
                 break;
             case 'b':
                 cout << optarg << endl;
                 break;
             case ':':
                 cerr << "Missing option." << endl;
                 exit(1);
                 break;
        }
    }

注意:a和b在标志后面带参数。

但是,如果我调用我的程序说,我会遇到问题

./myprog -a -b parameterForB

在我忘记了 parameterForA 的地方,parameterForA(由 optarg 表示)返回为 -b 并且 parameterForB 被认为是没有参数的选项,并且 optind 设置为 argv 中 parameterForB 的索引。

在这种情况下,期望的行为是 ':' 在找不到 -a 的参数后返回,并且 Missing 选项。 打印为标准错误。但是,这只发生在 -a 是传递给程序的最后一个参数的情况下。

我想问题是:有没有办法让 getopt() 假定没有选项会以 - 开头?

最佳答案

POSIX standard definition对于 getopt。它说

If it [getopt] detects a missing option-argument, it shall return the colon character ( ':' ) if the first character of optstring was a colon, or a question-mark character ( '?' ) otherwise.

关于那个检测,

  1. If the option was the last character in the string pointed to by an element of argv, then optarg shall contain the next element of argv, and optind shall be incremented by 2. If the resulting value of optind is greater than argc, this indicates a missing option-argument, and getopt() shall return an error indication.
  2. Otherwise, optarg shall point to the string following the option character in that element of argv, and optind shall be incremented by 1.

看起来 getopt 被定义为不做你想做的事,所以你必须自己实现检查。幸运的是,您可以通过检查 *optarg 并自己更改 optind 来做到这一点。

int c, prev_ind;
while(prev_ind = optind, (c =  getopt(argc, argv, ":a:b:c")) != EOF)
{
    if ( optind == prev_ind + 2 && *optarg == '-' ) {
        c = ':';
        -- optind;
    }
    switch ( …

关于c++ - getopt 无法检测到选项的缺失参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2219562/

相关文章:

c++ - dynamic_cast 向下转型 : How does the runtime check whether Base points to Derived?

c++ - 找不到匹配项

c - %g 浮点表示的最大字符串长度是多少?

c - 将操作数放在 getopt() 的前面

c++ - Unreal Engine 4.19 C++ Undeclared Identifier 错误,但它的代码已声明

c++ - 我无法理解一些 C++ 模板代码

c - 如何在 Perl 中有效解析表达式 '^#[0-9A-F]{2}\$[0-9A-F]{4}/$'

c++ - 获取 SQLite 结果中的列数

python - Python 的 argparse 可以像 gnu getopt 一样置换参数顺序吗?

c - 命令行错误消息的 "POSIX-defined format"是什么?哪个标准?