C语言 在带有非选项参数的 C 中使用 getopt

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18079340/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 07:04:31  来源:igfitidea点击:

Using getopt in C with non-option arguments

cargumentsargvgetoptgetopt-long

提问by Conor Taylor

I'm making a small program in C that deals with a lot of command line arguments, so I decided to use getopt to sort them for me.

我正在用 C 编写一个处理大量命令行参数的小程序,所以我决定使用 getopt 来为我排序。

However, I want two non-option arguments (source and destination files) to be mandatory, so you have to have them as arguments while calling the program, even if there's no flags or other arguments.

但是,我希望两个非选项参数(源文件和目标文件)是强制性的,因此您必须在调用程序时将它们作为参数,即使没有标志或其他参数。

Here's a simplified version of what I have to handle the arguments with flags:

这是我必须用标志处理参数的简化版本:

while ((c = getopt(argc, argv, "i:d:btw:h:s:")) != -1) {
    switch (c) {
        case 'i': {
            i = (int)atol(optarg);
        }
        case 'd': {
            d = (int)atol(optarg);
        }
        case 'b':
            buf = 1;
            break;
        case 't':
            time = 1;
            break;
        case 'w':
            w = (int)atol(optarg);
            break;
        case 'h':
            h = (int)atol(optarg);
            break;
        case 's':
            s = (int)atol(optarg);
            break;
        default:
            break;
    }
}

How do I edit this so that non-option arguments are also handled?

如何编辑它以便也处理非选项参数?

I also want to be able to have the non-options either before orafter the options, so how would that be handled?

我还希望能够在选项之前之后拥有非选项,那么如何处理呢?

回答by Klas Lindb?ck

getoptsets the optindvariable to indicate the position of the next argument.

getopt设置optind变量以指示下一个参数的位置。

Add code similar to this afterthe options loop:

在选项循环添加类似于此的代码:

if (argv[optind] == NULL || argv[optind + 1] == NULL) {
  printf("Mandatory argument(s) missing\n");
  exit(1);
}

Edit:

编辑:

If you want to allow options after regular arguments you can do something similar to this:

如果您想在常规参数之后允许选项,您可以执行类似以下操作:

while (optind < argc) {
  if ((c = getopt(argc, argv, "i:d:btw:h:s:")) != -1) {
    // Option argument
    switch (c) {
        case 'i': {
            i = (int)atol(optarg);
        }
        case 'd': {
            d = (int)atol(optarg);
        }
        case 'b':
            buf = 1;
            break;
        case 't':
            time = 1;
            break;
        case 'w':
            w = (int)atol(optarg);
            break;
        case 'h':
            h = (int)atol(optarg);
            break;
        case 's':
            s = (int)atol(optarg);
            break;
        default:
            break;
    }
    else {
        // Regular argument
        <code to handle the argument>
        optind++;  // Skip to the next argument
    }
}

回答by Madars Vi

Really good example could be found here: GNU LibcThe code:

可以在这里找到非常好的示例:GNU Libc代码:

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

int
main (int argc, char **argv)
{
int aflag = 0;
int bflag = 0;
char *cvalue = NULL;
int index;
int c;

opterr = 0;

while ((c = getopt (argc, argv, "abc:")) != -1)
switch (c)
{
case 'a':
    aflag = 1;
    break;
case 'b':
    bflag = 1;
    break;
case 'c':
    cvalue = optarg;
    break;
case '?':
    if (optopt == 'c')
    fprintf (stderr, "Option -%c requires an argument.\n", optopt);
    else if (isprint (optopt))
    fprintf (stderr, "Unknown option `-%c'.\n", optopt);
    else
    fprintf (stderr,
        "Unknown option character `\x%x'.\n",
        optopt);
    return 1;
default:
    abort ();
}

printf ("aflag = %d, bflag = %d, cvalue = %s\n",
    aflag, bflag, cvalue);

for (index = optind; index < argc; index++)
printf ("Non-option argument %s\n", argv[index]);
return 0;
}

It allows to have options before and after arguments. I did compile and run test example:

它允许在参数之前和之后有选项。我确实编译并运行了测试示例:

$ ./a.out aa ff bb -a -ctestparam hello
aflag = 1, bflag = 0, cvalue = testparam
Non-option argument aa
Non-option argument ff
Non-option argument bb
Non-option argument hello