Я хочу передать аргументы командной строки в 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;
}
Вам нужен дополнительный 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.
Вы эффективно проходите через массив полученных аргументов. Когда вы шагаете, вам нужно «потреблять» столько аргументов, сколько вы использовали. Каждое слово в командной строке становится одним аргументом (если только вы не объедините несколько слов в один аргумент с помощью кавычек). Когда вы обрабатываете что-то вроде -r a b
как одно целое, вы потребляете три аргумента.
Ваш код предполагает, что вы всегда используете пару аргументов. Обратите внимание, что вы можете не обработать аргументы вашего -r
флаг, если вы передаете ему только один аргумент: нет проверки для отсутствующего аргумента: вы проверяете, что у вас есть как минимум два оставшихся аргумента, но -r
Флаг требует всего три аргумента.