如何选择选项之一?

时间:2018-12-02 06:03:43

标签: c command-line-arguments unistd.h

我正在尝试POSIX getopt函数,但遇到了一些问题。我想通过命令行参数为应用程序提供一种模式(读或写)。所以我试图做这样的事情:

enum mode{
    read,
    write
};
enum mode mode;

int opt;
while((opt = getopt("rw")) != -1){
    switch(opt){
        case 'w':
            mode = write;
            break;
        case 'r':
            mode = read;
            break;
        default:
            fprintf(stderr, "Usage: %s [-r-w]\n", argv[0]");
            exit(1);
    }
}

问题在于它现在的工作方式,可以同时传递无意义的-r-w选项。我希望选择两种模式中的唯一一种。

这样做的“惯用”方法是什么?

3 个答案:

答案 0 :(得分:2)

这太主观了,不是一个好问题,但这是一些想法:

(1)一种方法是只有一种选择。读取默认行为,如果指定-w选项,则写入模式。

(2)某些Unix程序通过说“最后一个参数获胜”来解决该问题

(3)另一种方法是使用单独的变量,并检测设置两个标志的条件。

我已经看到所有三种方法。可能还有其他想法。

答案 1 :(得分:2)

如果是我,我可能会按照以下方式使用某些东西:

enum mode { DEFAULT, READ, WRITE };
enum mode mode = DEFAULT;

int opt;
while ((opt = getopt("rw")) != -1)
{
    switch (opt)
    {
    case 'w':
        if (mode == READ)
            err_exit("cannot use mutually exclusive options -r and -w");
        mode = WRITE;
        break;
    case 'r':
        if (mode == WRITE)
            err_exit("cannot use mutually exclusive options -r and -w");
        mode = READ;
        break;
    default:
        fprintf(stderr, "Usage: %s [-r|-w]\n", argv[0]);
        exit(1);
    }
}

if (mode == DEFAULT)
    mode = READ;    // Or write, whichever is your default

请注意,这避免了使用未初始化的变量mode

我假设一个合适的函数err_exit()会报告错误并退出。我的实现还有一个err_usage(),将使用err_usage("[-r|-w]");(并使用函数调用err_setarg0(argv[0])来记录程序名称)。您可以在SOQ子目录下的stderr.cstderr.h文件中找到我在GitHub上src/libsoq(堆栈溢出问题)存储库中的实现。

我还避免使用诸如readwrite之类的名称,因为它们也用于函数,因此被小写的枚举常量隐藏(它们在普通标识符名称空间中,相同作为函数和变量)。实际上,我可能会使用诸如OPT_(因此OPT_DEFAULTOPT_READOPT_WRITE)之类的前缀,以避免与名称的其他可能用法冲突。

答案 2 :(得分:2)

  

如何选择选项之一?
  JMeter vs Gatling

创建一个只能接受一种有效模式的助手功能。

import requests
from requests.adapters import HTTPAdapter
import time
from datetime import timedelta

def new_adapter():
    adapter =  HTTPAdapter()
    def new_send(request, **kwargs):
        start = time.perf_counter()
        try:
            resp = HTTPAdapter().send(request,**kwargs)
        except Exception as e:
            raise e
        finally:
            elapsed = time.perf_counter() - start
            elapsed = timedelta(seconds=elapsed)
            print("From new_adapter {}".format(elapsed.total_seconds()))
        return resp
    adapter.send = new_send
    return adapter

with requests.Session() as s:
    s.mount('https://', new_adapter())
    s.mount('http://', new_adapter())
    for url in ["http://127.0.0.1","http://github.com"]:
        try:
            starts = time.perf_counter()
            resp = s.get(url)
            elapsed = resp.elapsed.total_seconds()
        except Exception as e:
            elapsed = None
            #raise e
        print("From rough {}".format(timedelta(seconds=time.perf_counter() - starts).total_seconds()))
        print("From elapsed {}".format(elapsed))
        print()