C: параметры синтаксического анализа в правильном направлении
Я пытаюсь разобрать два варианта в программе на Си.
Программа называется так:
./a.out [OPTIONS] [DIRECTORY 1] [DIRECTORY 2]
Программа синхронизирует две директории и имеет две опции. (-r)
для рекурсивной синхронизации (папка внутри папки) и (-n)
скопировать файл с локального на удаленный, если он не существует в удаленном.
Options are:
-r : recursive
-n : copy file if it doesn't exist in remote folder
Так зовем:
./a.out -r D1 D2
будет рекурсивно синхронизировать все файлы и каталоги из D1
в D2
, Файлы представлены в D1
и не присутствует в D2
игнорируются
И зовет:
./a.cout -rn D1 D2
будет делать то же самое, но файлы, присутствующие в D1
и не присутствует в D2
копируются в D2
,
Проблема в том, что вызов ./a.out -rn
это не то же самое, что звонить ./a.out -nr
а также ./a.out -r -n
не работает ни потому, что (-n)
не является D1
,
Вот как я реализую главное.
int main(int argc, char** argv) {
int next_option = 0;
const char* const short_options = "hrn:";
const struct option long_options[] = {
{ "help", 0, NULL, 'h' },
{ "recursive", 1, NULL, 'r' },
{ "new", 1, NULL, 'n' },
{ NULL, 0, NULL, 0 }
};
int recursive = 0;
int new = 0;
do {
next_option = getopt_long(argc, argv, short_options, long_options, NULL);
switch(next_option) {
case 'r':
recursive = 1;
break;
case 'n':
new = 1;
break;
case 'h':
print_help();
return 0;
case -1:
break;
default:
print_help();
return -1;
}
} while(next_option != -1);
sync(argv[2], argv[3], recursive, new);
return EXIT_SUCCESS;
}
2 ответа
У вас есть две (потенциальные) проблемы здесь:
У вас есть шальные
:
в вашей короткой строке параметра. Это делает-n
выбрать опцию, которая проглатывает любое следующееr
, У вас также есть длинные параметры для обязательных аргументов.Вы жестко закодировали номера аргументов негибким способом и не проверяете их существование.
Попробуй это:
int main(int argc, char** argv) {
int next_option = 0;
const char* const short_options = "hrn";
extern int optind;
const struct option long_options[] = {
{ "help", no_argument, NULL, 'h' },
{ "recursive", no_argument, NULL, 'r' },
{ "new", no_argument, NULL, 'n' },
{ NULL, no_argument, NULL, 0 }
};
int recursive = 0;
int new = 0;
do {
next_option = getopt_long(argc, argv, short_options, long_options, NULL);
switch(next_option) {
case 'r':
recursive = 1;
break;
case 'n':
new = 1;
break;
case 'h':
print_help();
return 0;
case -1:
break;
default:
print_help();
return -1;
}
} while(next_option != -1);
if (optind + 1 >= argc)
return -1;
sync(argv[optind], argv[optind+1], recursive, new);
return EXIT_SUCCESS;
}
Проблема с использованием командной строки, такой как -r -n
потому что вы жестко закодировали индексы в вызове sync
, Вы не должны этого делать.
Если вы читаете getopt_long
Страница справочника (всегда, когда у вас есть проблемы с функцией!), тогда вы заметите эту строку:
Если дополнительных символов нет, getopt () возвращает -1. Тогда optind - это индекс в argv первого элемента argv, который не является опцией.
Прочитайте второе предложение внимательно.