Получить два параметра для main с одним необязательным аргументом

Я хочу передать аргументы командной строки в main. Это должно быть сделано с помощью спецификатора опции, например -a 4. Для одинарного символа и одиночного значения все работает хорошо, но при попытке передать два значения для каждого параметра он работает только при последнем введении.

Следующий код работает так, как хотел, при использовании так ./a.out -a 4 -b 6 -r 2 1

a:4
b:6
x_0:2
y_0:1

Однако используя ./a.out -r 2 3 -a 32 только значения по умолчанию для a а также b используются.

a:1
b:1
x_0:2
y_0:3

Это связано с приращением argv и argc?

Спасибо за вашу помощь.

Код: скомпилировать с g++ main.cc

//--------------------------------------
//  Includes
//--------------------------------------
#include <iostream>
#include <cstdlib>

//--------------------------------------
//  Function Declarations
//--------------------------------------
void getArgsToMain(int argc, char *argv[]);
void showVars();

//--------------------------------------
//  Variable declarations
//--------------------------------------
double a    = 1.;
double b    = 1.;
double x_0  = a;
double y_0  = 0.;

// typedefs and namespace
using namespace std;

// ===  FUNCTION  ======================
//         Name:  main
//  Description:
// =====================================
int main ( int  argc , char * argv[] )
{
getArgsToMain(argc, argv);
showVars();
return 0;
}// ----------  end of function main  ----------//--------------------------------------
//  Main function implementations
//--------------------------------------
void getArgsToMain(int argc, char *argv[])
{
while ((argc>1) && (argv[1][0]=='-'))
{
switch(argv[1][1])
{
case 'a':
a=atof(argv[2]);
break;
case 'b':
b=atof(argv[2]);
break;
case 'r':
x_0=atof(argv[2]);
if (!argv[3])
cout<<"Warning: No y_0 specified. Reverting to default."<<endl;
else
y_0=atof(argv[3]);
break;
default:
cout<<"Usage: blabla";
exit(0);
}
argv++;
argv++;
argc--;
argc--;
}
}

void showVars()
{
cout << endl;
cout << "a:" << a << endl;
cout << "b:" << b << endl;
cout << "x_0:" << x_0 << endl;
cout << "y_0:" << y_0 << endl;
}

1

Решение

Вам нужен дополнительный argv++, argc-- для ваших двух значений для варианта варианта. Проверьте также, если второе значение уже является следующей опцией.

case 'r':
x_0=atof(argv[2]);
if (!argv[3] || argv[3][0] == '-') {
cout<<"Warning: No y_0 specified. Reverting to default."<<endl;
} else {
y_0=atof(argv[3]);
argv++;
argc--;
}
break;

Как подсказал @ezod, вы можете использовать getopt, Увидеть Предоставление двух аргументов для параметра командной строки с использованием getopt
а также C getopt множественное значение для аналогичных требований в отношении getopt.

1

Другие решения

Вы эффективно проходите через массив полученных аргументов. Когда вы шагаете, вам нужно «потреблять» столько аргументов, сколько вы использовали. Каждое слово в командной строке становится одним аргументом (если только вы не объедините несколько слов в один аргумент с помощью кавычек). Когда вы обрабатываете что-то вроде -r a b как одно целое, вы потребляете три аргумента.

Ваш код предполагает, что вы всегда используете пару аргументов. Обратите внимание, что вы можете не обработать аргументы вашего -r флаг, если вы передаете ему только один аргумент: нет проверки для отсутствующего аргумента: вы проверяете, что у вас есть как минимум два оставшихся аргумента, но -r Флаг требует всего три аргумента.

1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector