Question

I have a program like this :

./server

Which has this usage :

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 

I was able to parse all the options with this code :

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);
}

But the thing is, for the -n option, I have to get the teams names like this :

./server -n team1 team2 team2

I just can't change the way it is.

Obviously I can do :

./server -n "team1 team2 team3"

And parse the teams, but it's for my firm and they don't want to put quotes around the team names, don't ask me why...

Any help in how can I get all the team names without using the quotes in shell?

Was it helpful?

Solution 2

You can also use optind. optint keeps track of the number of options encountered. optind points to the next index in argv[] that is encountered by getopt()

Therefore you can lookup in argv for whether there is a team. But for this to work you should omit the ":" in the optstring as in the next fragment "p:x:y:nc:t:" or decrement the value of optint before using it in the loop.

this is just a simple function to determine whether the loop must continue.

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

And this is what you do when you encounter the 'n' option you can also use the colon in the optstring, but then the encounter option is also counted and then i = optind - 1 might also work

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;

I hope this helps.

OTHER TIPS

I think you have three differen posibilities:

  1. use multiple '-n' parameters:

    ./server -n team1 -n team2 -n team3
    
  2. use a character like ',' as divider inside optarg

    ./server -n team1,team2,team3
    
  3. don't use getopt but parse argv for your own

Use getopt in else if (ch == 'n') branch to parse all teams until next option occurs.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top