Ian McGrath
Ian McGrath

Reputation: 1012

Correct way to use getopt/long_getopt

I know this topic has been beaten to death but I still couldn't find what I am searching for. I need to parse command line arguments in C++.

I cannot use Boost and using long_getopt

The issue is in casting, when I simply print the arguments , it works as expected in the loop but the value assigned to variables is not working somehow.

Here is the complete , compilable program.

#include <iostream>
#include <getopt.h>
using namespace std;

int main(int argc, char *argv[])
{
    int c;
    int iterations = 0;
    float decay = 0.0f;
    int option_index = 0;
    static struct option long_options[] =
    {
        {"decay",  required_argument, 0, 'd'},
        {"iteration_num",  required_argument, 0, 'i'},
        {0, 0, 0, 0}
    };

    while ((c = getopt_long (argc, argv, "d:i:",
                long_options, &option_index)  ) !=-1)
     {
        /* getopt_long stores the option index here. */

        switch (c)
        {
        case 'i':
        //I think issue is here, but how do I typecast properly? 
        // especially when my other argument will be a float 
        iterations  = static_cast<int>(*optarg);    
        cout<<endl<<"option -i value "<< optarg;
        break;

        case 'd':
        decay = static_cast<float>(*optarg);
        cout<<endl<<"option -d with value "<<optarg;
        break;

     }
    }//end while
    cout << endl<<"Value from variables, which is different/not-expected";
    cout << endl<< decay << endl << iterations <<  endl;
return(0);
}

As I mentioned in the comment - think the problem is in typecasting, how to do it properly? If there is any other way which is better, please do let me know.

You can run the program as --- ./program-name -d .8 -i 100

Thank you for your help. I am new to Unix and C++ but trying very hard to learn it :)

Upvotes: 3

Views: 4477

Answers (2)

gumik
gumik

Reputation: 623

Because optarg is char*. It's plain text. So if you give your program .8 as argument then optarg is a string ".8" and casting it to float doesn't work. Use for example atoi and atof funcions (declared in 'stdlib.h') to parse string as int and float. In your code it would be:

iterations = atoi(optarg);
decay = atof(optarg);

Upvotes: 1

thiton
thiton

Reputation: 36049

You are casting a string (char*) value to integer values, which is very different from parsing it. By casting, you use the ASCII value of the first character as a numerical value, while by parsing a string, you try to interpret the whole string as a text and convert it into a machine-readable value format.

You need to use a parsing function like:

std::stringstream argument(optarg);
argument >> iterations;

or

boost::lexical_cast<int>(optarg);

or (C-style)

atoi(optarg)

Upvotes: 4

Related Questions