1

I need to parse command line arguments in C. My arguments are basically int or float with default values and range constrains.

I've started to implement something that look like this:

option_float(float* out, int argc, char* argv, char* name, description,
    float default_val, int is_optional, float min_value, float max_value)

which I call for example with:

float* pct;
option_float(pct, argc, argv, "pct", "My super percentage option", 50, 1,
    FALSE, 0, 100)

However I don't want to reinvent the wheel!

My objective is to have error checking of range constraints, throw an error when the option is not optional and is not set. And generate the help message usually given by usage() function.

The usage text would look like this:

--pct     My super percentage option (default : 50). Should be in [0, 100]

I've started with getopt but it is too limited for what I want to do and I feel it still requires me to write too much code for a simple use case like this.

What alternatives would you recommend?

2
  • 2
    Argument-parsing helpers for C/UNIX goes over some of the options (ad there are probably other questions on the site, it's common need). I don't know one that meets all you requirements, but gengetopt would reduce the amount of code you have to write. Commented Dec 26, 2010 at 20:08
  • gengetopt is unfortunately GPL but gopt and glib seem to be good candidates. I'll explore these two options. Thanks Commented Dec 27, 2010 at 16:23

1 Answer 1

0

Assuming you are coding for Linux...

Try getopt_long (man 3 getopt_long) for the double-dash options.

Also, try making the validators to be generic functions and let getopt/getopt_long to the hard part of the parsing and checking required arguments to options.

In any case, if you want to use your functions as defined, your example call will not work as defined.

A simplified example:

int main( int argc, char **argv )
{
  float pct = 0.0
  if( !GetArgs(argc, argv, &pct) )
    DoStuff(pct)
}

int GetArgs( int argc, char **argv, float *thePct )
{
  extern char *optarg;
  int  rc = 0;

  (*thePct) = 50.0  /* default val */

  while( (opt = getopt(argc, argv, "hp:")) != -1 )
  {
    switch( opt )
    {
      case  'p':
            (*thePct) = atof( optarg );
            break;

      case  'h':
            MyUsage();  /* Explain everything */
            rc = -1;
            break;
    }
  }

  if( !rc )
  {
    rc = ValidatePct( (*thePct),   /* value to check */
                      0.0,         /* low pct val */
                      100.0 );     /* hi pct val */

    /* Other validations here */

    if( !rc )
      MyUsage();
  }
}

This will allow a call like:

$ myprogram -p 45.0

If you stick to the parsers getopt and getopt_long, you can also make command lines that take options followed by N number of other arguments like grep does, for instance:

grep -in -e "SomeRegex" file1, file2, ..., fileN

Out of sheer curiosity, you aren't a PERL programmer, are you?

Sign up to request clarification or add additional context in comments.

2 Comments

that's a nice and simple design around getopt but still a bit too verbose for the Python programmer I am ;) I'll explore gopt and glib as suggested above. thanks
That's the name of the game with C. It is a much lower level language than Python.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.