我正在尝试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
选项。我希望选择两种模式中的唯一一种。
这样做的“惯用”方法是什么?
答案 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.c
和stderr.h
文件中找到我在GitHub上src/libsoq(堆栈溢出问题)存储库中的实现。
我还避免使用诸如read
和write
之类的名称,因为它们也用于函数,因此被小写的枚举常量隐藏(它们在普通标识符名称空间中,相同作为函数和变量)。实际上,我可能会使用诸如OPT_
(因此OPT_DEFAULT
,OPT_READ
,OPT_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()