使用getopt的多个整数参数?

时间:2016-09-19 19:27:47

标签: c getopt

使用getopt时处理多个整数参数的最佳方法是什么?我必须能够在命令行输入这样的内容:calc -a 100 50,它将加起来100和50。

    while ((opt = getopt(argc, argv, "adms")) != -1)
    {

       value = atoi(argv[optind + 1]);
      printf("value : %d\n", value);

        switch (opt)
        {
        case 'a': aFlag = 1; num1 = atoi(argv[optind]);
                  sum = num1 + value;
                  printf("%d + %d =  %d\n" , num1, value, sum);
                  break;
        case 'd': dFlag = 1;
                  break;
        case 'm':  break;
        case 's':  break;
        default:
            fprintf(stderr, "%s: unknown option %c\n", argv[0], optopt);
return 1;
        }
    }

     if (aFlag == 1)
        {
                  num1 = atoi(argv[optind]);
                  sum = num1 + value;
                  printf("%d + %d =  %d\n" , num1, value, sum);
        }
     if (dFlag == 1)
        {
                  num2 = atoi(argv[optind]);
                  sub = num2 / value;
                  printf("%d / %d =  %d\n" , num2, value, sum);
        }

3 个答案:

答案 0 :(得分:3)

我认为你所追求的界面可能是:

./program -a 100 50

接受单个选项-a(替代-m-s-d),然后将其他参数作为数字列表处理,而不是作为值附在选项上。除非您计划使用:

,否则此工作正常
./program -a 100 50 -m 20 30

进行加法和乘法。

如果有人无法下定决心,你想做什么:

./program -am 100 50

如果是错误,还是应该-a-m获胜?你可以争论任何具有某种程度一致性的人。不过,我会犯一个错误。

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

static int op_add(int a, int b) { return a + b; }
static int op_sub(int a, int b) { return a - b; }
static int op_mul(int a, int b) { return a * b; }
static int op_div(int a, int b) { return a / b; }

int main(int argc, char **argv)
{
    int (*fun)(int, int) = 0;
    char op;
    int opt;

    while ((opt = getopt(argc, argv, "adms")) != -1)
    {
        if (fun != 0)
        {
            fprintf(stderr, "%s: you can't use two operations\n", argv[0]);
            return 1;
        }
        switch (opt)
        {
        case 'a': fun = op_add; op = '+'; break;
        case 'd': fun = op_div; op = '/'; break;
        case 'm': fun = op_mul; op = '*'; break;
        case 's': fun = op_sub; op = '-'; break;
        default:
            fprintf(stderr, "%s: unknown option %c\n", argv[0], optopt);
            return 1;
        }
    }
    if (fun == 0 || optind + 2 != argc)
    {
        fprintf(stderr, "Usage: %s [-adms] num1 num2\n", argv[0]);
        return 1;
    }

    int res = fun(atoi(argv[optind]), atoi(argv[optind+1]));
    printf("%s %c %s = %d\n", argv[optind], op, argv[optind+1], res);
    return 0;
}

对“数字”参数中的值进行错误检查是不可思议的邋((意思是,不存在)。零检查也没有划分。但这至少会产生合理的答案。拥有一个保存函数指针和操作字符的结构数组可能会更好,但这种改进是供您处理的。

如果您需要负数,请使用--标记选项的结尾:

$ ./program -m -- -39 -75
-39 * -75 = 2925
$

如果你不确定它,int (*fun)(int, int)是一个指向函数的指针,该函数接受两个int参数并返回int结果。它允许代码选择在运行时执行哪个函数。

答案 1 :(得分:0)

使用getopt(),一个选项最多只能占用一个参数。如果您希望程序使用getopt()处理其命令行,并且它必须接受您描述的参数

calc -a 100 50

,你不能重复选项,那么唯一可行的解​​决方案是创建一个或两个整数非选项参数而不是-a选项的参数。我建议制作两个(或所有)非选项参数。因此,你可能会有这样的事情:

int result = getopt(argc, argv, "asmd");

switch (result) {
    case 'a':
        // careful: getopt() will be confused by negative numbers
        if (getopt(argc, argv, "asmd") != -1) {
            fprintf(stderr, "usage: %s -a|-s|-m|-d <operands>\n", argv[0]);
            exit(1);
        }
        do_add(argv + optind);
        break;

    case 's':
        // ...
}

getopt()返回-1后,optindargv中的索引,超过了最后一个选项(+/-选项参数)处理的索引。

答案 2 :(得分:0)

getopt()手册页的摘录清楚地表明,每个答案(以及原始问题)都没有显示对getopt的理解:

optstring是一个包含合法选项字符的字符串     如果这样的字符后跟冒号,         [然后]选项需要一个参数,         所以getopt()放置一个指针             对于同一个argv-element中的以下文本,
            或以下argv元素的文本,             在optarg。

您的代码还应允许以下内容:

如果getopt()无法识别选项字符,         它会向stderr输出一条错误消息,         将角色存储在optopt中,
        并返回&#39;?&#39;。

最后这个(允许-位于命令行的任何位置:

默认情况下,getopt()会在扫描时置换argv的内容,这样就可以了        最终所有非选区都在最后。