2010-08-16 66 views
3

如何从命令行参数 - “尾部-10”获得选项-10。 getopt函数查找'1'字符。但我如何访问字符串“10”C getopt - <integer>

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

+0

我怀疑getopt不支持单短划线多字符选项,但我不确定 – 2010-08-16 03:35:55

回答

3

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

编辑:其实我想我误读了你想要的东西。如果你想-后跟任何数字被解释为与该数值的选项,我不认为有任何版本的getopt将工作。您无法将每个单一数字作为选项进行特殊处理,如果您只是简单地告诉getopt所有数字都是可选参数,则-123将被解释为-1选项,参数为23(这很好,你可以从那里解释它),但是一个唯一的-1将导致下一个argv元素获得eaten作为-1的参数,这很难或不可能从中恢复。

+1

我不认为getopt_long会这样做,它需要参数前面的“ - ” – 2010-08-16 04:01:57

+0

如果我记得正确地说,'getopt_long'包含一个'long-only'选项(或者一个单独的函数'getopt_longonly'?),它可以接受一个'-'或者一个双'--'。 – 2010-08-16 04:52:38

+0

谢谢。我很想不使用getopt函数。 通过getopt“-123”是选项:-1和optarg:NULL。我们松开了字符串“23”,它不在optarg中。我可以用其他方式访问它吗? – Ramya 2010-08-16 12:36:34

3

这里发生了什么事c语言自带绝对关于处理命令行选项的正确方法没有标准。

此外,unix世界相当长一段时间没有这样的标准(相信在Unix Haters Handbook (PDF link)中有关于它的全部内容)。

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

但是在东西安定下来之后(偶尔会有),人们在处理选项的“常规”方式中添加了新功能,只要他们似乎是个好主意。现在,这是一个非常不错的选择,这tail会希望有数调整往往比任何其他要素线,所以使得它容易敲几下键盘调整必须好像在当时是个好主意...

+0

upvote for up up'unix haters handbook'! – AoeAoe 2014-03-20 16:46:11

0

我从来没有像getopt那么多,所以我做了平常的事情,并重新发明了车轮。我打电话给我的解决方案argopt。您可以从https://github.com/colding/argopt获取源和手册页。我认为,它比getopt更容易使用。

+0

-1:虽然你的解决方案可能是好的,但这不是推动它的地方(尤其是如果你重新发明车轮的话)。另外,你似乎是唯一开发/使用它的人。 – jmiserez 2014-03-29 13:27:48

0

在可能的情况下,我建议通过将数字作为选项参数(例如-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, "")) != -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, ""); 
       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; 
    } 
} 

您可以替换getoptgetopt_long,并根据需要增加额外的短期或长期的选项。