1

strong textI am trying to get the argguments from this command :

./cube -d ../../data/input_small_id -q ../../data/query_small_id -k 5 -M 15 -p 6 -o out

And I have a problem getting the k,M and p. To be specific I want k,M and p to be optional_requirements and my program gets only the default numbers I give them. All of the numbers are integers(k,M,probes).I have done this:

void CubeUtils::getArgs(int argc,char **argv) {

    int c ;
    while (1) {
        static struct option long_options[] =
        {
            //These options don’t set a flag.
            //We distinguish them by their indices. 
            {"d"         , required_argument , 0 , 'd'},
            {"q"        , required_argument , 0 , 'q'},
            {"k"    , optional_argument , 0 , 'k'},
            {"M"           , optional_argument , 0 , 'M'},
            {"probes"           , optional_argument , 0 , 'p'},
            {"o"          , required_argument , 0 , 'o'},
            {0, 0, 0, 0}
        };

        // getopt_long stores the option index here. 
        int option_index = 0;

        c = getopt_long (argc, argv, "d:q:k::M::p::o:a:h",
        long_options, &option_index);

        // Detect the end of the options. 
        if (c == -1)
            break;
        switch (c) {
            case 'd':
                params.input_file.insert(0,optarg);
                break;
            case 'q':
                params.query_file.insert(0,optarg);
                break;
            case 'k':
                if (optarg) {
                    params.K = atoi(optarg);
                }
                else
                    params.K = 3 ;
                break;
            case 'M':
                if (optarg) {
                    params.M = atoi(optarg);
                }
                else
                    params.M = 10 ;
                break;
            case 'p':
                if (optarg) {
                    params.probes = atoi(optarg);
                }
                else
                    params.probes = 2 ;
                break;
            case 'o':
                params.output_file.insert(0,optarg);
                break;
            case '?':
            // getopt_long already printed an error message. 
                break;
            default:
                abort ();
        }
    }
}

Params is struct which holds the arguments:

struct ParametersCube
{
    string input_file;
    string query_file;
    int K;
    int M;
    int probes ;
    string output_file;
    float radius;

};

When its executed I only take the default numbers and never the numbers I give via command line.

Jeffrey
  • 11,063
  • 1
  • 21
  • 42

1 Answers1

1

This seems to be expected behaviour with optional arguments.

Quoting the optarg manpage:

optstring is a string containing the legitimate option characters. If such a character is followed by a colon, the option requires an argument, so getopt() places a pointer to the following text in the same argv-element, or the text of the following argv-element, in optarg. Two colons mean an option takes an optional arg; if there is text in the current argv-element (i.e., in the same word as the option name itself, for example, "-oarg"), then it is returned in optarg, otherwise optarg is set to zero.

…and the getopt manpage:

A simple short option is a '-' followed by a short option character. If the option has a required argument, it may be written directly after the option character or as the next parameter (ie. separated by whitespace on the command line). If the option has an optional argument, it must be written directly after the option character if present.

Personally I find that strange, but I can confirm that if you change those arguments to:

-k5 -M15 -p6

then it works.

See also:

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055