Search code examples
c++getopt-long

Cpp: How can I get the long-name of an option using getopt.h


Hey I have a function to check the given arguments for my program.

I want to get the long-name of the given users argument. Problem is currently he gives me weird high numbers example 32758 while my struct has only 9 elements...

I have to use it for university otherwise I would use the boost library....

#include <iostream>
#include <getopt.h>

int main(int argc, char *argv[])
{
    // Standard directories
    std::string outputDir = "PROJECT_PATH\\output\\"; /**< Output directory */

    // Options
    const struct option longOptions[3] = {
        {"output-dir", required_argument, nullptr, 'O'},
        {"help", no_argument, nullptr, 'h'},
        {nullptr, 0, nullptr, 0}};

    int opt;
    int option_index;
    while ((opt = getopt_long(argc, argv, "O:h", longOptions, &option_index)) != -1)
    {
        std::cout << "Long option index: " << option_index << std::endl;
        std::cout << "Option name: " << longOptions[option_index].name << std::endl;
        switch (opt)
        {
        case 'O':
            outputDir = optarg;
            break;
        case 'h':
            // printHelpText();
            exit(0);
        case '?':
            if ((optopt == 'O' || optopt == 'h'))
            {
                std::cout << "OK ... option '-" << static_cast<char>(optopt) << "' without argument"
                          << std::endl;
                exit(1);
            }
            else if (isprint(optopt))
            {
                std::cerr << "ERR ... Unknown option -" << static_cast<char>(optopt) << std::endl;
                exit(-1);
            }
            else
            {
                std::cerr << "ERR ... Unknown option character \\x" << static_cast<char>(optopt) << std::endl;
                exit(-1);
            }
        }
    }
    return 0;
}

Solution

  • Looking at the documentation and source code for getopt_long() it does not seem to calculate the index of the long option if it parses a short option so you are seeing uninitialized data in option_index.

    It will only be filled with data if a long option is actually present.

    If you need this value, write your own loop through the array looking for the returned short option.

    Here is a link to getopt_long() in android copied from BSD. I would assume this is the same on all other platforms.

    https://android.googlesource.com/platform/bionic/+/a27d2baa/libc/unistd/getopt_long.c