Получить несколько значений для одной и той же опции

У меня есть такая программа:

./server

Который имеет это использование:

Usage : 
-p  Port to use (4242 by default)
-x  Map width (20)
-y  Map height (20)
-n  Team name (name_team1 name_team2)
-c  Players per team
-t  Delay 

Я смог разобрать все варианты с помощью этого кода:

int parse_cmd(int argc, char **argv, t_args *a)
{
    char ch;

    if (argv[1] && argv[1][0] != '-')
        usage();
    while ((ch = getopt(argc, argv, "p:x:y:n:c:t:")) != -1)
    {
        if (ch == 'p')
            a->port = atoi(optarg);
        else if (ch == 'x')
            a->x = atoi(optarg);
        else if (ch == 'y')
            a->y = atoi(optarg);
        else if (ch == 'n')
            a->teams = name_teams(optarg);
        else if (ch == 'c')
            a->size = atoi(optarg);
        else if (ch == 't')
            a->delay = atoi(optarg);
        else
            usage();
    }
    if (check_values(a) == FALSE)
        return (FALSE);
    return (TRUE);
}

Но дело в том, что для опции -n мне нужно получить такие имена команд:

./server -n team1 team2 team2

Я просто не могу изменить то, что есть.

Очевидно, я могу сделать:

./server -n "team1 team2 team3"

И разобрать команды, но это для моей фирмы и они не хотят заключать названия команд в кавычки, не спрашивайте почему...

Любая помощь в том, как я могу получить все имена команд без использования кавычек в оболочке?


person Yanis Boucherit    schedule 02.07.2013    source источник


Ответы (3)


Вы также можете использовать optind. optint отслеживает количество встречающихся вариантов. optind указывает на следующий индекс в argv[], с которым сталкивается getopt()

Поэтому вы можете посмотреть в argv, есть ли команда. Но чтобы это работало, вы должны опустить ":" в строке опций, как в следующем фрагменте "p:x:y:nc:t:", или уменьшить значение optint перед его использованием в цикле.

это просто простая функция, чтобы определить, должен ли цикл продолжаться.

int 
is_team ( const char* team ) {
    if ( team == NULL)
        return 0;
    else if ( team[0] == '-' ) /*new argument*/
        return 0;
    else
        return 1;
}

И это то, что вы делаете, когда сталкиваетесь с опцией «n», вы также можете использовать двоеточие в строке опций, но тогда также учитывается опция встречи, и тогда i = optind - 1 также может работать

case 'n':
    { /*note this scope is significant*/
        int i;
        for ( i = optind ; is_team(argv[i]); ++i  ) {
            printf ( "team = %s\n", argv[i]);
            //argument = ++*optarg;
        }
    }
    break;

Надеюсь, это поможет.

person hetepeperfan    schedule 02.07.2013
comment
Это сделало работу! Спасибо ! - person Yanis Boucherit; 05.07.2013

Я думаю, у вас есть три разных возможности:

  1. использовать несколько параметров '-n':

    ./server -n team1 -n team2 -n team3
    
  2. используйте символ типа ',' в качестве разделителя внутри optarg

    ./server -n team1,team2,team3
    
  3. не используйте getopt, а анализируйте argv для своего собственного

person Ingo Leonhardt    schedule 02.07.2013

Используйте getopt в ветке else if (ch == 'n') для анализа всех команд, пока не появится следующая опция.

person kotlomoy    schedule 02.07.2013