#c #linux #getopt-long #command-line-arguments
#c #linux #getopt-long #аргументы командной строки
Вопрос:
Я использую getopt_long
на компьютере GNU / Linux. Инициализировать список параметров как:
static struct option long_options[] = {
{"mode", required_argument, 0, 9},
{0, 0, 0, 0}
};
Есть следующая строка кода
c = getopt_long(argc, argv, "", long_options, index_ptr);
Когда я запускаю свою программу с помощью command:
prog --mode
Показанная выше строка кода возвращает ‘?’ на c, но не ‘:’, как ожидалось согласно getopt(3)
справочной странице: «Error и -1 возвращает те же значения, что и для getopt()»
Да, при использовании / разборе коротких опций можно было бы написать в списке опций что-то вроде «: m:», чтобы переменная c в отсутствующем аргументе содержала ‘:’, а не ‘?’, но что нужно сделать, чтобы различать два случая (отсутствующий аргумент, недопустимый параметр) при разборе только длинных опций?
Как можно отличить недопустимый параметр от параметра с отсутствующим обязательным аргументом?
Комментарии:
1. Почему в
long_options
массиве вы использовали 9 в качестве возвращаемого значения вместо символа ‘9’ и почемуoptstring/shortopts
параметр не содержит «9:»? (см. Пример синтаксического анализа длинных параметров )2. @DavidBowling
.val
являетсяint
, но в основном используется, когда.flag
указатель не равен NULL. Поскольку9
is не может быть использован для определения аргумента shortcut, лучше использовать символ типа'm'
(для mode).3. Да, я прочитал раздел getopt[_long] справочного руководства glibc, прежде чем задавать вопрос. Но не ясно, что должно быть возвращено в этом случае.
4. @Piquard, на самом деле не имеет значения, что они возвращают, потому что я хочу различать два случая ошибок (отсутствующий аргумент, недопустимый параметр), и я хочу анализировать только длинные варианты.
Ответ №1:
Единственный способ, который я вижу для достижения вашей цели по различению недопустимого параметра и допустимого параметра с отсутствующим аргументом, — это установить для has_arg
поля структуры options значение optional_argument
, а затем вручную проверить наличие аргумента. Тогда getopt_long()
будет возвращено значение ‘?’ только при наличии недопустимого параметра, и вы можете проверить, есть ли у указанного параметра аргумент, заглянув в optarg
. Вот пример:
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
int main(int argc, char *argv[])
{
int i, opt;
int index = -1;
static struct option long_options[] = {
{"mode", optional_argument, NULL, 'm'},
{0, 0, 0, 0}
};
/* suppress error messages */
//opterr = 0;
while ((opt = getopt_long(argc, argv, "", long_options, amp;index)) != -1) {
if (opt == '?') {
/* do something, perhaps: */
//printf("Invalid option n");
// exit(EXIT_FAILURE);
}
if (opt == 'm' amp;amp; optarg == NULL) {
printf("Missing argument in '--mode' optionn");
exit(EXIT_FAILURE);
}
}
return 0;
}
Комментарии:
1. Я тоже думал об этом, проблема в том, что тело с условными обозначениями if будет увеличиваться, если у вас будет много опций, таких как —mode .
2. @BulatM.— рассматривали ли вы возможность использования Argp ? Это выглядит немного сложнее, чем функции в
getopt
стиле, но выглядит более гибким. Возможно, он сможет делать то, что вы хотите.