Правильный способ использования getopt / long_getopt - PullRequest
2 голосов
/ 17 сентября 2011

Я знаю, что эта тема была избита до смерти, но я все еще не мог найти то, что я ищу. Мне нужно проанализировать аргументы командной строки в C ++.

Я не могу использовать Boost и использовать long_getopt

Проблема в приведении, когда я просто печатаю аргументы, в цикле все работает как положено, но значение, присвоенное переменным, не работает.

Вот полная, компилируемая программа.

#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);
}

Как я уже упоминал в комментарии - думаю, что проблема заключается в типизировании, как это сделать правильно? Если есть другой способ, который лучше, пожалуйста, дайте мне знать.

Вы можете запустить программу как --- ./program-name -d .8 -i 100

Спасибо за вашу помощь. Я новичок в Unix и C ++, но очень стараюсь выучить это:)

Ответы [ 2 ]

4 голосов
/ 17 сентября 2011

Вы приводите строковое (char *) значение к целочисленным значениям, что сильно отличается от его анализа. При преобразовании вы используете значение ASCII первого символа в качестве числового значения, в то время как при разборе строки вы пытаетесь интерпретировать всю строку как текст и конвертировать ее в формат машиночитаемого значения.

Вам нужно использовать функцию разбора, например:

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

или

boost::lexical_cast<int>(optarg);

или (в стиле C)

atoi(optarg)
0 голосов
/ 17 сентября 2011

Потому что optarg это char *. Это простой текст. Так что если вы зададите в качестве аргумента вашу программу .8, то optarg будет строкой ".8" ​​и приведение ее к плавающей точке не будет работать. Используйте, например, функции atoi и atof (объявленные в 'stdlib.h'), чтобы проанализировать строку как int и float. В вашем коде это будет:

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