Нельзя сравнивать строки, подобные этой:
if (optarg == "insertion") algorithm = 0;
Вам нужно использовать strcmp()
или эквивалентный, например:
if (strcmp(optarg, "insertion") == 0) algorithm = 0;
Могут быть и другие проблемы, но это сразу приходит на ум.
Работа с optarg
выполнением optarg++
, вероятно, не очень хорошая идея. Это информация из функции для вас; это глупо менять его. Вы можете взять копию указателя, а затем увеличить его, шагая по строке, на которую он указывает. Конечно, нет никакой гарантии, что в аргументе для -k
будет пробел, и это, вероятно, является источником вашей проблемы, наряду с неправильным использованием сравнения указателей символов вместо использования strcmp()
или эквивалентного.
Вы, похоже, пропускаете break
после case 'k':
.
* * * * * bool endOption
внутри тела цикла нечетно: оно устанавливается равным false
на каждой итерации; оно проверяется, пока оно еще false
, поэтому break
не выполняется; устанавливается true
, когда getopt_long()
возвращает 0
; но значение сбрасывается до следующей итерации. Возможно, вам следует объявить эту переменную вне основного цикла while ((c = getopt_long(...)) != -1)
. Тогда он будет вести себя разумно (хотя вам, вероятно, следует прекратить цикл, если он установлен перед повторным вызовом getopt_long()
, поэтому, возможно, условие для него должно быть в нижней части основного цикла while
.
Изменение проверки цикла при обработке -k
на while (strcmp(optarg, "") != 0)
(ключевое отличие - пропущенный пробел между двумя двойными кавычками), и затем я получаю вменяемое поведение. Обратите внимание на то, как я описал параметры, чтобы видеть, что выполняется. Когда я запустил сравнение со строкой, содержащей пробел, я получил необычный дамп своего окружения до того, как цикл завершился. Именно такие вещи приводят к дампам ядра.
#include <getopt.h>
#include <vector>
#include <iostream>
#include <cstdlib>
using namespace std;
static struct option long_options[] =
{
{"algorithm", required_argument, 0, 'a'},
{"reverse", no_argument, 0, 'r'},
{"key", required_argument, 0, 'k'},
{"output", required_argument, 0, 'o'},
{"help", no_argument, 0, 'h'},
{"version", no_argument, 0, 'V'},
{0, 0, 0, 0}
};
int main(int argc, char **argv)
{
vector<int> sortOrder;
int option_index = 0;
int c;
bool reverseFlag = false;
int algorithm = 1;
bool fileFlag = false;
//Getopt to get the correct options from the command line.
while ((c = getopt_long(argc, argv, "a:rk:o:hV", long_options, &option_index)) != -1)
{
bool endOption = false;
if (endOption) break;
switch (c)
{
case 0:
cerr << "Found 0 value\n";
endOption = true;
break;
case 'a':
cerr << "Found -a option: " << optarg << endl;
if (strcmp(optarg, "insertion") == 0)
algorithm = 0;
break;
case 'r':
cerr << "Found -r option\n";
reverseFlag = true;
break;
case 'k':
cerr << "Found -k option: " << optarg << endl;
while (strcmp(optarg, "") != 0)
{
if (strcmp(optarg, ",") == 0)
optarg++;
else
{
cerr << "pushback <<" << optarg << ">>\n";
sortOrder.push_back(atoi(optarg)); //error here
optarg++;
}
}
break;
case 'o':
cerr << "Found -o option: " << optarg << endl;
fileFlag = true;
break;
case 'h':
case 'V':
default:
cerr << "You have entered an incorrect flag, do it better" << endl;
break;
}
}
}
Когда он запускается как:
./getopt -k 2,1
Я получил вывод:
Found -k option: 2,1
pushback <<2,1>>
pushback <<,1>>
pushback <<1>>
Возможно, вы захотите изменить сравнение с:
if (strcmp(optarg, ",") == 0)
до:
if (*optarg == ',')
Вы можете даже разумно изменить условие цикла на:
while (*optarg != '\0')
Таким образом, избегайте strcmp()
в целом. Кстати, я не уверен, какой заголовок вытащил в <cstring>
, но один из них сделал.
Для справки, я тестирую на Mac Mini с MacOS X 10.7.2 (Lion) и использую компилятор G ++, i686-apple-darwin11-llvm-g++-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)
.