страница людей, конечно, не Документируйте это очень хорошо, но исходный код немного помогает.
Вкратце: вы должны сделать что-то вроде следующего (хотя это может быть немного более-педантичный):
if( !optarg
&& optind < argc // make sure optind is valid
&& NULL != argv[optind] // make sure it's not a null string
&& '\0' != argv[optind][0] // ... or an empty string
&& '-' != argv[optind][0] // ... or another option
) {
// update optind so the next getopt_long invocation skips argv[optind]
my_optarg = argv[optind++];
}
/* ... */
Из замечаний, предшествующих _getopt_internal:
.. .
Если getopt
находит другой символ опции, она возвращает этот символ, обновление optind
и nextchar
, чтобы следующий вызов getopt
мог возобновить сканирование со следующим символом или ARGV-элементом.
Если символов больше нет, getopt
возвращает -1. Тогда optind
- это индекс в ARGV первого элемента ARGV , который не является вариантом. (В ARGV-элементы были переставлены так, что те, которые не являются вариантами в настоящее время приходит в последней очереди.) <-- a note from me: if the 3rd argument to getopt_long starts with a dash, argv will not be permuted
...
Если символ в строка_опциях следует двоеточие, что означает, что он хочет ARG , , поэтому следующий текст в том же элементе ARGV или текст следующего ARGV-element, возвращается в optarg
.Два двоеточия означают опцию, что хочет необязательный аргумент arg; если в текущем ARGV-элементе есть текст, возвращается в optarg
, иначе optarg
установлен на ноль.
...
... хотя вы должны сделать некоторое чтение между строк. Следующее делает то, что вы хотите:
#include <stdio.h>
#include <getopt.h>
int main(int argc, char* argv[]) {
int getopt_ret;
int option_index;
static struct option long_options[] = {
{"praise", required_argument, 0, 'p'}
, {"blame", optional_argument, 0, 'b'}
, {0, 0, 0, 0}
};
while(-1 != (getopt_ret = getopt_long( argc
, argv
, "p:b::"
, long_options
, &option_index))) {
const char *tmp_optarg = optarg;
switch(getopt_ret) {
case 0: break;
case 1:
// handle non-option arguments here if you put a `-`
// at the beginning of getopt_long's 3rd argument
break;
case 'p':
printf("Kudos to %s\n", optarg); break;
case 'b':
if( !optarg
&& NULL != argv[optindex]
&& '-' != argv[optindex][0]) {
// This is what makes it work; if `optarg` isn't set
// and argv[optindex] doesn't look like another option,
// then assume it's our parameter and overtly modify optindex
// to compensate.
//
// I'm not terribly fond of how this is done in the getopt
// API, but if you look at the man page it documents the
// existence of `optarg`, `optindex`, etc, and they're
// not marked const -- implying they expect and intend you
// to modify them if needed.
tmp_optarg = argv[optindex++];
}
printf("You suck");
if (tmp_optarg) {
printf (", %s!\n", tmp_optarg);
} else {
printf ("!\n");
}
break;
case '?':
printf("Unknown option\n");
break;
default:
printf("Unknown: getopt_ret == %d\n", getopt_ret);
break;
}
}
return 0;
}
Я документирую это здесь с ответом, поэтому другим людям не нужно ударять головой о стену. – hayalci