Search code examples
cposixgetopt

Correct or decent getopts_long usage?


What it the correct usage if I want this behaviour:

$ ./a.out --help for printing help information

$ ./a.out --version for printing the program version

I managed to code this so that it takes the arguments but I don't know a good / correct way to separate the messages since they are the same case.

static struct option long_options[] = {
        {"help",  no_argument,       0,  0 },
        {"version", no_argument,       0,  0 },
        {0,         0,                 0,  0 }
};


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


    while (1) {
        int this_option_optind = optind ? optind : 1;
        int option_index = 0;


        c = getopt_long(argc, argv, "",
                        long_options, &option_index);
        if (c == -1)
            break;

        switch (c) {
            case 0:
                printf("option %s", long_options[option_index].name);
                if (optarg)
                    printf(" with arg %s", optarg);
                printf("\n");
                return 0;

            case '0':
            case '1':
            case '2':
                if (digit_optind != 0 && digit_optind != this_option_optind)
                    printf("digits occur in two different argv-elements.\n");
                digit_optind = this_option_optind;
                printf("option 2 2 %c\n", c);
                return 0;

            case 'a':
                printf("option a\n");
                break;

            case 'b':
                printf("option b\n");
                break;

            case 'c':
                printf("option c with value '%s'\n", optarg);
                break;

            case 'd':
                printf("option d with value '%s'\n", optarg);
                break;

            case '?':
                break;

            default:
                printf("?? getopt returned character code 0%o ??\n", c);
        }
    }

    if (optind < argc) {
        printf("non-option ARGV-elements: ");
        while (optind < argc)
            printf("%s ", argv[optind++]);
        printf("\n");
    }

...

Solution

  • Here you have an example:

    while (1)
    {
        int option_index = 0;
        static struct option long_options[] = {
            {"with_param", required_argument, 0, 'p'},
            {"version", no_argument, 0, 'v'},
            {"help", no_argument, 0, 'h'},
            {0, 0, 0, 0}
        };
    
        option = getopt_long(argc, argv, "p:vh",
                             long_options, &option_index);
        if (option == -1)
            break;
    
        switch (option) {
        case 'p':
        {
            store_parameter(optarg);
            break;
        }
        case 'v':
        {
            print_version();
            break;
        }
        case 'h':
        {
            print_help();
            exit(EXIT_SUCCESS);
            break;
        }
        default:
        {
            fprintf(stderr, "Error (%s): unrecognized option.\n", __FUNCTION__);
            print_help();
            exit(EXIT_FAILURE);
            break;
        }
        } /* end switch */
    }
    

    Notice the string "p:vh" as parameter of getopt_long, which allows you to also use short options. (":" follows options with a required argument)