首页 > 解决方案 > 在检查选项之前处理 getopt 中的非选项参数

问题描述

我正在编写一个程序,我想在检查标志之前获取非选项参数。

例如,如果参数是./a.out -a -b 50 filename

我想使用filename然后做task_a()和/或task_b()取决于标志。filename可以是任何参数argv[]

int opt;
float value;
while ((opt = getopt(argc, argv, "ab:")) != -1)
    case 'a':
        task_a(filename);
        break;
    case 'b':
         value = atof(optarg);
         task_b(filename, value);
         break;

所以基本上我需要filename在我的任务中使用它之前提取它。我该如何实施?

标签: cunixgetopt

解决方案


getopt 将按照在命令行中找到它们的顺序向您传递命令行参数。这通常不是您想要处理它们的顺序。

相反,让你的程序在执行操作之前先设置它的选项——比如(给定#include <stdbool.h>):

// Set the defaults
bool doTaskA = false;
book doTaskB = false;
float brightness = -1;

int opt;
float value;
while ((opt = getopt(argc, argv, "ab:")) != -1) {
    case 'a':
    doTaskA = true;
    break;
case 'b':
     doTaskB = true;
     brightness = atof(optarg);
     break;
}

filename = ....,,

if (doTaskA) {
      task_a(filename);
}

if (doTaskB) {
    task_b(filename, brightness);
}

我选择了名称“brightness”作为一个有意义的属性名称——当然你应该选择你自己的。作为一种好的做法,不要将变量命名为“optionA”或类似的名称——变量名称应该描述它们是什么,而不是具体的实现细节。

总是想象你的选项会随着时间的推移而改变字母(现在的选项“a”可能会在六个月后变成选项“R”)——这样的变化不应该影响除了“getopt”参数和“case”语句之外的任何东西。

编辑更改:我最初用“if (brightness >= 0.0)”写了这个,但认为通常单独的 doTaskB 变量是更清晰、更明确的方法,不会限制参数的可能值。


推荐阅读