0

I am trying to parse command line arguments in C. Currently, I am using getopt do the parse. I have something like this:

#include <unistd.h>

int main(int argc, char ** argv)
{
   while((c=getopt(argc, argv, "abf:")) != -1)
   {
     switch(c)
     {
        case 'a':
        break;
        case 'b':
        break;
        case 'f':
        puts(optarg);
        break;
        case ':':
        puts("oops");
        break;
        case '?'
        puts("wrong command");
        break;
     }
   }
}

then need to use ./a.out -fto run the program, and -f is the command element, but looks like -f must start with a '-', if I do not want the command element starts with '-', i.e, using ./a.out f instead of ./a.out -f, how to achieve it?

if getopt does not support parsing a command line in this way, are there any other library to use in C?

23
  • 4
    Why don't you want flags to start with -? That's the UNIX convention. Commented Sep 9, 2014 at 19:24
  • Agreed. Making your command line options "special" doesn't help anyone. Commented Sep 9, 2014 at 19:26
  • Unrelated: It would likely help immensely if c were declared. Commented Sep 9, 2014 at 19:26
  • 1
    And if you do want to be a special little snowflake, Google is your friend. en.wikibooks.org/wiki/A_Little_C_Primer/… Commented Sep 9, 2014 at 19:26
  • 1
    @mafso The git options cannot be parsed using the standard getopt/getopt_long API -- they use their own custom parser to handle it. It all depends on how complex you want the command-line interface to be (e.g. if you want options before the command to be handled differently to the ones after). Commented Sep 9, 2014 at 19:58

3 Answers 3

1

The argc and argv variables give you access to what you're looking for. argc is "argument count" and argv is "argument vector" (array of strings).

getopt is a very useful and powerful tool, but if you must not start with a dash, you can just access the argument array directly:

int main( int argc, char** argv) {
    if( argc != 1) { /* problem! */ }
    char * argument = argv[1]; // a.out f ... argv[1] will be "f"
}
Sign up to request clarification or add additional context in comments.

4 Comments

As far as I know, argv[0] is the name of the executable, and argv[1] the first argument passed to the program.
Except that argv[0] is generally related to the program's name. You should rather inspect argv[1] when argc>1
are there any ways that I can use getopt without starting with '-'?
Not easily. Getopt uses - to start argument lines. I suppose you could rewrite argv to include - on arguments before sending them through getopt, but that would be more difficult to get correctly than manually parsing the args.
1

You could use (on Linux with GNU libc) for parsing program arguments:

and of course you could parse program arguments manually, since they are given thru main(int argc, char**argv) on Linux (with the guarantee that argc>0, that argv[0] is "the program name" -e.g. to find it in your $PATH when it contains no / ..., that argv[argc] is the NULL pointer, and that before that every argv[i] with i<argc and i>0 is a zero-terminated string. See execve(2) for more.

GNU coding standards: command line interfaces document quite clearly some conventions. Please, obey at least the --help and --version conventions!

You might also be concerned by customizing the shell auto-completion facilities. GNU bash has programmable completion. zsh has a sophisticated completion system.

Remember that on Posix and Linux the globbing of command words is done by the shell before starting your program. See glob(7).

Comments

0

The getopt library will stop parsing at the first non-option argument. For command-based programs, this will be at the command name. You can then set optind to the index to start at and run getopt again with the command-specific arguments.

For example:

// general getopts
if (optind >= argc) return 0; // error -- no command
if (strcmp(argv[optind], "command") == 0)
{
    ++optind; // move over the command name
    // 'command'-specific getopts
    if (optind >= argc) return 0; // error -- no input
}

This should allow git-like command-line parsing.

Comments

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.