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

在带有非选项参数的C中使用getopt,c,arguments,argv,getopt,getopt-long,C,Arguments,Argv,Getopt,Getopt Long,我正在用C语言编写一个小程序,处理许多命令行参数,所以我决定使用getopt对它们进行排序 但是,我希望两个非选项参数(源文件和目标文件)是必需的,因此在调用程序时必须将它们作为参数,即使没有标志或其他参数 下面是我必须处理带有标志的参数的简化版本: while ((c = getopt(argc, argv, "i:d:btw:h:s:")) != -1) { switch (c) { case 'i': { i = (int)atol(opta

我正在用C语言编写一个小程序,处理许多命令行参数,所以我决定使用getopt对它们进行排序

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

下面是我必须处理带有标志的参数的简化版本:

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;
    }
}
我如何编辑它,以便也处理非选项参数


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

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

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

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

如果要在常规参数后允许选项,可以执行类似的操作:

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
    }
}
while(optind
optind++;//跳到下一个参数
}
}

这里有一个很好的例子:代码:

#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;
}

默认情况下,getopt()在argv扫描时排列其内容, 所以最终所有的非选项都在最后。另外两个 还实现了扫描模式。如果 optstring为“+”或环境变量POSIXLY_正确 设置,则一旦出现非选项参数,选项处理就会停止 遇到。如果optstring的第一个字符为“-”,则 每个非选项argv元素的处理方式与参数相同 用于字符代码为1的选项。(这由程序使用。) 它们是为了在中预期选项和其他argv元素而编写的 任何一种顺序,都与这两种顺序有关。)the 特殊参数“-”强制结束选项扫描 扫描模式的选择


好的,但是如果强制参数在可选参数之前,我的循环将退出,因此只有强制参数将被处理,而不是可选参数。我如何解决这个问题?通常要求选项在参数之前。只需在
man
页面中指定它。是的,我知道,但例如使用ssh命令,-p标志可以出现在强制执行之前或之后username@server争论,我只是想知道怎么做that@gatopeich
argv[argc]
由C标准保证为
NULL
,因此我提供的代码应该可以正常工作。您在“编辑”下提供的示例显然不起作用(至少在Linux上),我不敢相信,自从这篇文章第一次发布以来,没有人注意到这一点。使用Mac OSX版本的getopt时,这不起作用。在linux glibc中,optind将指向强制参数,即使它们在getopt()之后位于选项后面,而您的引用可能会告诉我们当前的问题,请详细说明您的答案以解决该问题“如何编辑此文件,以便同时处理非选项参数?”
$ ./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