c - optarg 值是否在对 getopt 的连续调用中保持不变?

标签 c getopt

通过实验,我似乎可以捕获 optarg 的连续值。迭代时 int getopt(int argc, char * const argv[], const char *optstring)并稍后引用它们,如以下示例程序中所示:

// main.c

#include <stdio.h>
#include <unistd.h>

int main( int argc, char* argv[] )
{
  int opt;
  char o;
  char* a = NULL;
  char* b = NULL;

  while ( -1 != ( opt = getopt( argc, argv, "abcd:e:" ) ) )
  {
    char o = opt & 0xFF;

    switch ( o )
    {
      case 'a':
      {
        printf( "%c (%p): [%s]\n", o, optarg, (NULL == optarg ? "" : optarg ) );
        break;
      }
      case 'b':
      {
        printf( "%c (%p): [%s]\n", o, optarg, (NULL == optarg ? "" : optarg ) );
        break;
      }
      case 'c':
      {
        printf( "%c (%p): [%s]\n", o, optarg, (NULL == optarg ? "" : optarg ) );
        break;
      }
      case 'd':
      {
        printf( "%c (%p): [%s]\n", o, optarg, (NULL == optarg ? "" : optarg ) );
        a = optarg;
        break;
      }
      case 'e':
      {
        printf( "%c (%p): [%s]\n", o, optarg, (NULL == optarg ? "" : optarg ) );
        b = optarg;
        break;
      }
    }
  }

  printf( "(%p): [%s]\n", a, (NULL == a ? "" : a ) );
  printf( "(%p): [%s]\n", b, (NULL == b ? "" : b ) );

  return 0;
}

编译和示例执行:
> gcc -g main.c && ./a.out -dabc -e def -a
d (0x7fffe8d1d2b2): [abc]
e (0x7fffe8d1d2b9): [def]
a ((nil)): []
(0x7fffe8d1d2b2): [abc]
(0x7fffe8d1d2b9): [def]

问题 : 这个有效吗? IE。是连续的非空 optarg值在 getopt() 的连续迭代后有效和/或它的最终迭代(当它返回 -1 时)? IE。捕获连续值并稍后引用它们是否安全(即没有 strdup ing它们)?我不想假设我的实验代码通常是正确的。

手册页指出有一个 extern char* optarg但没有指定它是否可以被 getopt() 的连续调用重用.

(由于 getopt 的参数是 argcargv ,这意味着 optarg 设置为 argv 的偏移量,在这种情况下,我认为捕获其连续值是安全的,但我想以了解这是否是正确的猜测)。

最佳答案

根据POSIX specification of getopt :

The getopt() function shall return the next option character (if one is found) from argv that matches a character in optstring, if there is one that matches. If the option takes an argument, getopt() shall set the variable optarg to point to the option-argument as follows:

  1. If the option was the last character in the string pointed to by an element of argv, then optarg shall contain the next element of argv, and optind shall be incremented by 2. If the resulting value of optind is greater than argc, this indicates a missing option-argument, and getopt() shall return an error indication.

  2. Otherwise, optarg shall point to the string following the option character in that element of argv, and optind shall be incremented by 1.


(强调我的。)
这说 optarg始终指向 argv 的元素.它从不制作副本。
argv 的元素只要您的程序运行,您的代码就有效(无需复制)。

注意。 POSIX 页面还显示了 example of command line options with arguments这基本上等同于您的版本:
char *ifile;
...
while ((c = getopt(argc, argv, ":abf:o:")) != -1) {
    switch(c) {
    ...
    case 'f':
        ifile = optarg;
        break;
    ...

关于c - optarg 值是否在对 getopt 的连续调用中保持不变?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53507713/

相关文章:

c - 字符串矩阵输入输出

c++ - 如何将 C 程序转换为类

c - 在 make_request 中使用什么样的自旋锁?

C 编程 - getopt

python - 如何在python中获取没有名称的参数

c - 微 Controller C 代码的单元测试模式

c - 使用 TF_SessionRun 在 C(而非 C++)中运行 TensorFlow 图形时出现段错误

bash - 如何在 bash 中多次调用 getopts

c - 多个逗号分隔值的 getopt 错误处理

C getopt_long 选项的两个必需参数