Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何选择其中一个选项?_C_Command Line Arguments_Unistd.h - Fatal编程技术网

C 如何选择其中一个选项?

C 如何选择其中一个选项?,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

我正在试验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
选项,这是无意义的。我只想选择两种模式中的一种


“惯用”的方法是什么?

这是一个非常主观的问题,这不是一个很好的问题,但这里有一些想法:

(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将超出函数的范围。艾尔