getopt,optarg和可选参数

时间:2014-01-14 21:03:44

标签: c gcc getopt

这个问题特别关注gct中可选参数的getopt。当一个选项被定义为具有可选参数且没有给出参数时,optarg被设置为空指针或指向空字符串的指针。手册似乎没有处理这种情况。行为是否得到保障?

百里

2 个答案:

答案 0 :(得分:2)

带有可选参数的

getopt是POSIX函数的实现定义扩展。如果文档中没有说明它的行为方式,则optarg == NULL的显式检查是最安全的。如果它不是NULL,我个人不会想象一个空字符串会表示缺少一个参数,但它可以。

当没有检测到参数时,我自己的实现将optarg设置为NULL,但它可以很容易地指向包含0字节的静态对象的内存地址作为读取的第一个字节,例如char noarg = 0;函数的源文件中的getopt。顺便说一句,GNU libc实现还将其设置为NULL,而不记录当前的行为。

如果您想要在任何一种行为中保持安全,特别是由于缺乏文档,我建议您执行以下操作:

if (optarg && *optarg) {
    /* Argument present */
}
else {
    /* No argument */
}

答案 1 :(得分:1)

如果您按POSIX getopt()定义,则定义行为:

  

如果它检测到缺少的option-argument,如果optstring的第一个字符是<colon>':',它将返回<colon>个字符(<question-mark>)否则字符('?')。

请注意,唯一可以检测到缺少选项参数的时间是最后一个参数是有效选项字符之一,并且没有额外参数是缺少参数。这意味着在任何命令的调用中你只能有一个缺少的参数(这实际上是没用的。)

如果您使用GNU getopt,则规则类似,但细节不同:

  

此字符串中的选项字符后面可以跟冒号(‘:’),表示它需要一个必需的参数。如果选项字符后跟两个冒号(‘::’),则其参数是可选的;这是一个GNU扩展。

     

getopt有三种方法可以处理非选项argv元素之后的选项。特殊参数‘--’在所有情况下都强制选项扫描结束。

这是一个过度陈述,IIRC。如果-f选项采用参数,则编写-f --会为您提供--的选项参数。

  
      
  • 默认情况下,在扫描时会置换argv的内容,以便最终所有非选项都在最后。这允许以任何顺序给出选项,即使对于未编写的程序也是如此。
  •   
  • 如果options参数字符串以连字符(‘-’)开头,则会对此进行特殊处理。它允许返回不是选项的参数,就好像它们与选项字符‘\1’相关联。
  •   
  • POSIX要求以下行为:第一个非选项停止选项处理。通过设置环境变量POSIXLY_CORRECT或使用加号(‘+’)开始options参数字符串来选择此模式。
  •   
     

getopt函数返回下一个命令行选项的选项字符。当没有更多选项参数可用时,它返回-1。可能还有更多非选项参数;您必须将外部变量optindargc参数进行比较才能检查此内容。

     

如果选项有参数,getopt通过将参数存储在变量optarg中来返回参数。您通常不需要复制optarg字符串,因为它是指向原始argv数组的指针,而不是可能被覆盖的静态区域。

     

如果getoptargv中找到未包含在options中的选项字符或缺少选项参数,则返回‘?’并设置外部变量{{ 1}}到实际的选项字符。如果选项的第一个字符是冒号(optopt),则‘:’返回getopt而不是‘:’以指示缺少选项参数。此外,如果外部变量‘?’非零(这是默认值),opterr将输出错误消息。

这表示您需要查看getopt的返回值,并将选项字符串的第一个字符设置为getopt(),以便知道何时缺少参数。同样,我的回忆是你最终只能拥有一个可选参数,但是自从我上次对系统提供的:变体进行了大量检查以来已经有好几年了。