【问题标题】:C getopt -<integer>C getopt -<整数>
【发布时间】:2010-08-16 03:31:52
【问题描述】:

如何从命令行参数“tail -10”中获取选项-10。 getopt 函数找到 '1' 字符。但是如何访问字符串 "10"

如果这可以通过 getopt_long 完成,一个示例会有所帮助。谢谢。

【问题讨论】:

  • 我怀疑 getopt 不支持单破折号多字符选项,但我不确定

标签: c getopt


【解决方案1】:

除非您打算将-1 用作以0 作为其参数的选项,否则答案是您不打算这样做。 getopt 仅用于处理符合标准 POSIX 实用程序选项语法的选项。可以使用 GNU getopt_long 来实现此目的,或者您可以编写自己的 argv 解析器(很简单)。

编辑:实际上我认为我误读了您想要的内容。如果您希望 - 后跟任何数字被解释为具有该数值的选项,我认为没有任何版本的 getopt 可以工作。您无法将每个数字作为选项进行特殊处理,如果您只是告诉 getopt 所有数字都是带参数的选项字符,-123 将被解释为带有参数的 -1 选项的23(这很好,你可以从那里解释它),但是一个单独的-1 将导致下一个argv 元素将eaten 作为-1 的参数,这很难或不可能恢复。

【讨论】:

  • 我不认为getopt_long会这样做,它需要在参数前面--
  • 如果我没记错的话,getopt_long 包含一个“long-only”选项(或者可能是一个单独的函数 getopt_longonly?),它接受单个 - 或双 --
  • 谢谢。我很想不使用 getopt 函数。通过 getopt 的“-123”是选项:-1 和 optarg:NULL。我们松开字符串“23”,它不在 optarg 中。我可以通过其他方式访问它吗?
  • 决定不使用getopt。谢谢。
【解决方案2】:

这里发生的情况是 c 语言附带绝对没有关于处理命令行选项的正确方法的标准。

此外,unix 世界已经有很长一段时间没有这样的标准了(相信在Unix Haters Handbook (PDF link) 中有一个完整的部分)。

因此,人们编写了 ad hoc 处理机制。这些最终演变为一个通用(ish)标准,getopt 诞生了(在贝尔实验室)。后来我们得到了 GNU getoptgetopt_long。然而,这些不是必需的,一些程序仍然以自己的方式管理事情。

但在事情安定下来之前(有时是之后),人们在“通常”的处理选项的方式中添加了新功能只要他们看起来是个好主意。现在,tail 会比任何其他功能更频繁地调整 number 行,这是一个不错的选择,因此使其简单很少调整击键在当时一定是个好主意...

【讨论】:

    【解决方案3】:

    我从来没有那么喜欢 getopt,所以我照常做,重新发明了轮子。我称我的解决方案为 argopt。您可以在https://github.com/colding/argopt 获取源代码和手册页。我认为它比 getopt 更易于使用。

    【讨论】:

    • -1:虽然您的解决方案可能很好,但这不是推动它的地方(特别是如果您正在重新发明轮子)。此外,您似乎是唯一一个开发/使用它的人。
    【解决方案4】:

    如果可能,我建议更改命令参数语法以避免使用数字参数,方法是将数字作为选项参数传递(例如 -n -5)或仅在 -- 选项分隔符之后允许它。

    对于无法更改参数语法的情况,BUGS section of the BSD getopt(3) man page 记录了一种执行此操作的方法。我已经调整了他们的解决方案以避免optreset,即not specified by POSIXnot supported by glibc

    int ch;
    long num;
    char *numarg;
    
    while ((ch = getopt(argc, argv, "0123456789")) != -1) {
        switch (ch) {
        case '0': case '1': case '2': case '3': case '4':
        case '5': case '6': case '7': case '8': case '9':
            numarg = argv[optind - 1];
            if (numarg[0] == '-' && numarg[1] == ch && numarg[2] == '\0') {
                num = '0' - ch;
            } else if ((numarg = argv[optind]) != NULL && numarg[1] == ch) {
                char *ep;
                int numoptind = optind;
    
                num = strtol(numarg, &ep, 10);
                if (*ep != '\0') {
                    fprintf(stderr, "illegal number -- %s\n", numarg);
                    return EXIT_FAILURE;
                }
    
                /* Advance getopt internal state to next argument. */
                while (optind == numoptind) {
                    ch = getopt(argc, argv, "0123456789");
                    assert(ch >= '0' && ch <= '9');
                }
            } else {
                fprintf(stderr, "number after other options -- %s\n", numarg);
                return EXIT_FAILURE;
            }
            break;
    
        default:
            /* Unrecognized option character.  Error printed by getopt. */
            return EXIT_FAILURE;
        }
    }
    

    您可以将getopt 替换为getopt_long,并根据需要添加额外的短选项或长选项。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-04-25
      • 1970-01-01
      • 1970-01-01
      • 2012-11-07
      • 2020-07-18
      • 1970-01-01
      • 2017-10-07
      相关资源
      最近更新 更多