0

好的,所以基本上我getopt_long只想在用户提供命令行选项的情况下修改标志变量。否则,我希望单独留下旗帜。我已经找到了解决方案,但它不是很漂亮。特别是,如果有很多标志,那么这会变得非常冗长。有没有更好的办法?:

#include <getopt.h>
#include <stdlib.h>
#include <stdio.h>

// I would like this function to only override myflag and myvariable if the user supplies them.
int parse_commandLineOptions(int argc, char *argv[], int *pointer_myflag){

  // Non-flag parameters "need" to be static or global to be accessible to getopt_long()
  static int set_myflag, unset_myflag;
  static struct option longopts[] = {

    // This is what I'd really like to do, but it's not permitted because myflag isn't static.
    // Do you haz teh codez?
    //{"set",        no_argument,       pointer_myflag, true},
    //{"unset",      no_argument,       pointer_myflag, false}

    // Instead this is the best I've come up with.
    {"set",          no_argument,       &set_myflag, 1},
    {"unset",        no_argument,       &unset_myflag, 1}
  };

  // This normally wouldn't be empty.
  char shortopts[] = "";

  int curChar=0;
  while(curChar!=-1){

    // Get the character representing the current command-line argument
    int option_index=0;
    curChar=getopt_long(argc, argv, shortopts, longopts, &option_index);
    if(curChar== -1)
      break;
    switch(curChar){

    // The user supplied one of the flag-setting options.
    case 0:
      break;

    // Normally I would parse non-flag parameters here.
    //case 'x':
    //  do something.

    // getopt_long will itself print an error message in this case.
    case '?':
      fprintf(stderr, "# Usage: not what you did.\n");
      exit(1);

    // This should never happen.
    default:
      fprintf(stderr, "# Error: Could not parse curChar in parse_commandLineOptions().\n");
      exit(1);

    } // Closes switch(curChar)

  } // Closes while(curChar!=-1)

  // Normally I would parse non-argument parameters here.

  // :(
  if(set_myflag) *pointer_myflag=1;
  else if(unset_myflag) *pointer_myflag=0;

  return 0;

}

int main(int argc, char *argv[]){

  // If the user supplies --set, myflag will be 1
  // If the user supplies --unset, myflag will be 0
  // If the user doesn't supply anything, myflag will be left as is.
  int myflag=1337;
  parse_commandLineOptions(argc, argv, &myflag);
  printf("myflag = %d\n", myflag);

}
4

2 回答 2

0

我所要做的就是丢失 longopts 上的 static 关键字!

#include <getopt.h>
#include <stdlib.h>
#include <stdio.h>

// This function only overrides myflag and myvariable if the user supplies them.
int parse_commandLineOptions(int argc, char *argv[], int *pointer_myflag){

  // ALL YOUR BASE ARE BELONG TO US!
  struct option longopts[] = {
    {"set",        no_argument,       pointer_myflag, 1},
    {"unset",      no_argument,       pointer_myflag, 0}
  };

  // This normally wouldn't be empty.
  char shortopts[] = "";

  int curChar=0;
  while(curChar!=-1){

    // Get the character representing the current command-line argument
    int option_index=0;
    curChar=getopt_long(argc, argv, shortopts, longopts, &option_index);
    if(curChar== -1)
      break;
    switch(curChar){

    // The user supplied one of the flag-setting options.
    case 0:
      break;

    // Normally I would parse non-flag parameters here.
    //case 'x':
    //  do something.

    // getopt_long will itself print an error message in this case.
    case '?':
      fprintf(stderr, "# Usage: not what you did.\n");
      exit(1);

    // This should never happen.
    default:
      fprintf(stderr, "# Error: Could not parse curChar in parse_commandLineOptions().\n");
      exit(1);

    } // Closes switch(curChar)

  } // Closes while(curChar!=-1)

  // Normally I would parse non-argument parameters here.

  // :)
  return 0;

}

int main(int argc, char *argv[]){

  // If the user supplies --set, myflag will be 1
  // If the user supplies --unset, myflag will be 0
  // If the user doesn't supply anything, myflag will be left as is.
  int myflag=1337;
  parse_commandLineOptions(argc, argv, &myflag);
  printf("myflag = %d\n", myflag);

}
于 2014-06-24T00:05:10.787 回答
-1

伙计,看看这里的代码。我认为它正在做你想要的,除了它不是使用true/false整数而是整数。

特别是,检查这些行:

/* Flag set by ‘--verbose’. */
static int verbose_flag;

static struct option long_options[] = {
    /* These options set a flag. */
    {"verbose", no_argument,       &verbose_flag, 1}, // HERE
    {"brief",   no_argument,       &verbose_flag, 0}, // AND HERE!
    /* These options don't set a flag.
    We distinguish them by their indices. */
    {"add",     no_argument,       0, 'a'},
    /* ... */
    {0, 0, 0, 0}
};

这是我用于我的程序的方法:

/** Little hack to hide the enum from the global scope */
class EFlags {
    public:
        enum Type {
            HELP,
            FLAG_A,
            FLAG_B,
            COUNT
        };
};

/* Using static to keep everything private to my cpp file */
static int g_flags[EFlags::COUNT];

/** List of options accepted by the program */
static const struct option g_option_list[] = {
    /* These options set a flag. */
    { "help"        , no_argument       , &g_flags[EFlags::HELP]    , 1 },
    { "optionA"     , no_argument       , &g_flags[EFlags::FLAG_A]  , 1 },
    { "nooptionA"   , no_argument       , &g_flags[EFlags::FLAG_A]  , 0 },
    { "optionB"     , no_argument       , &g_flags[EFlags::FLAG_B]  , 1 },
    { "nooptionB"   , no_argument       , &g_flags[EFlags::FLAG_B]  , 0 }
    {0, 0, 0, 0}
};

int main( int argc, char * argc[] ) {
    for( int i = 0; i < EFlags::COUNT; i++ ) {
        g_flags[i] = 0;
    }

    ...
}
于 2014-06-23T19:03:21.217 回答