C 如何选择其中一个选项?
我正在试验POSIXC 如何选择其中一个选项?,c,command-line-arguments,unistd.h,C,Command Line Arguments,Unistd.h,我正在试验POSIXgetopt函数,遇到了一些问题。我想通过命令行参数为应用程序提供一种模式(读或写)。所以我试着这样做: enum mode{ read, write }; enum mode mode; int opt; while((opt = getopt("rw")) != -1){ switch(opt){ case 'w': mode = write; break; case
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
选项,这是无意义的。我只想选择两种模式中的一种
“惯用”的方法是什么?这是一个非常主观的问题,这不是一个很好的问题,但这里有一些想法: (1) 一种方法是只有一种选择。默认行为为读取,如果指定了-w选项,则模式为写入 (2) 一些Unix程序通过说“最后一个参数获胜”来解决这个问题 (3) 另一种方法是使用单独的变量,并检测设置了两个标志的条件
我已经看到了所有三种方法的使用。可能还有其他想法。这太主观了,这不是一个好问题,但这里有一些想法: (1) 一种方法是只有一种选择。默认行为为读取,如果指定了-w选项,则模式为写入 (2) 一些Unix程序通过说“最后一个参数获胜”来解决这个问题 (3) 另一种方法是使用单独的变量,并检测设置了两个标志的条件
我已经看到了所有三种方法的使用。可能还有其他想法。如果是我的话,我可能会使用以下方法:
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
请注意,这样可以避免使用未初始化的变量模式
我假设有一个合适的函数err\u exit()
,它报告错误并退出。我的实现还有一个err\u用法()
,将使用err\u用法(“[-r |-w]”)
(并使用函数调用err_setarg0(argv[0])来记录程序名)。在GitHub上的my(Stack Overflow Questions)存储库中,您可以在子目录中找到这些问题的实现,即文件stderr.c
和stderr.h
我还避免使用诸如
read
和write
之类的名称,因为它们也用于函数,因此被小写枚举常量隐藏(它们位于普通标识符名称空间中,与函数和变量相同)。事实上,我可能会使用前缀,例如OPT\u
(因此OPT\u DEFAULT
,OPT\u READ
,OPT\u WRITE
),以避免与名称的其他可能用法发生冲突。如果是我,我可能会使用以下内容:
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
请注意,这样可以避免使用未初始化的变量模式
我假设有一个合适的函数err\u exit()
,它报告错误并退出。我的实现还有一个err\u用法()
,将使用err\u用法(“[-r |-w]”)
(并使用函数调用err_setarg0(argv[0])来记录程序名)。在GitHub上的my(Stack Overflow Questions)存储库中,您可以在子目录中找到这些问题的实现,即文件stderr.c
和stderr.h
我还避免使用诸如read
和write
之类的名称,因为它们也用于函数,因此被小写枚举常量隐藏(它们位于普通标识符名称空间中,与函数和变量相同)。事实上,我可能会使用前缀,例如OPT_
(因此OPT_DEFAULT
,OPT_READ
,OPT_WRITE
),以避免与名称的其他可能用法发生冲突
如何选择其中一个选项?创建一个仅允许一种有效模式的助手函数
enum mode get_mode(void) {
int opt = getopt("rw");
if (opt != -1 && getopt("rw") == -1) {
switch(opt){
case 'w': return write;
case 'r': return read;
}
}
fprintf(stderr, "Usage: %s [-r-w]\n", argv[0]");
exit(1);
}
如何选择其中一个选项?创建一个仅允许一种有效模式的助手函数
enum mode get_mode(void) {
int opt = getopt("rw");
if (opt != -1 && getopt("rw") == -1) {
switch(opt){
case 'w': return write;
case 'r': return read;
}
}
fprintf(stderr, "Usage: %s [-r-w]\n", argv[0]");
exit(1);
}
在您的情况下,1)验证:选择“无模式”是否有问题?2) 第二次选择同一模式是否有问题?@chux 1)是的,我希望用户只选择一种模式。在您的情况下,1)验证:选择“无模式”是否有问题?2) 第二次选择相同的模式是否有问题?@chux 1)是的,我希望用户只选择一种模式。如果代码是
If(mode==READ)
-->If(mode!=DEFAULT)
,则会检测到类似-w-w
的用法。是的,@chux:我确实有默认值
当我开始键入时,但我决定需要重新处理错误消息-需要两个测试来报告两个不同的错误条件(两个相互排斥的选项,而不是重复一个选项;我讨厌说“许多条件中的一个错误”的草率错误消息)。总的来说,设置相同标志的重复选项不那么严重。最后的决定取决于我们没有的背景。(我还假设如果代码是If(mode==READ)
-->If(mode!=DEFAULT)
,那么像-w-w
这样的用法就会被检测到。是的,@chux:我确实有!=默认值
当我开始键入时,但我决定需要重新处理错误消息-需要两个测试来报告两个不同的错误条件(两个相互排斥的选项,而不是重复一个选项;我讨厌说“许多条件中的一个错误”的草率错误消息)。总的来说,设置相同标志的重复选项不那么严重。最后的决定取决于我们没有的背景。(我还假设实际上除了-r
和-w
-帮助、版本等之外,还有更多的选项)我喜欢这个函数的简洁性,但是(与操作代码一样)这个代码不调用与POSIX兼容的getopt。缺少argc和argv参数。此外,argv将超出函数的范围。艾尔