views:

72

answers:

2

Hi guys, i have a program that needs command line arguments in the form :

./my_program -m256M -tm -t some_other_file

The "some_other_file" argument is not bound to -t (-t it's just another functionality) so i can't take it as the optarg of any of the flags, neither can i assume it is the last argument in the list.

How can i do this?

Thanks

+2  A: 

Is that what you want?

int main(int argc, char* argv[]){
//...
int i=1;

for(; i<argc; i++){
   if(argv[i][0] != '-'){
      printf("%s\n", argv[i]);
      //break; //if you dont want all arguments that don't start with - or --
   }
}

//...
return 0;
}

$ gcc dsad.c && ./a.out -m256M -tm -t some_other_file more_file
some_other_file
more_file
$ gcc dsad.c && ./a.out -m256M -tm -t
$ gcc dsad.c && ./a.out -m256M -tm -t some_other_file --another
some_other_file

N 1.1
No, it's not .That starts from the assumption that the "some_other_file" is the last one, but it's not that way, that if condition will skip any argument after that.
Simone Margaritelli
The above code does not assume "some_other_file" is last one. Try it out.
N 1.1
When you don't find anymore '_' you break the for loop ...
Simone Margaritelli
Well, you could remove the break :)
N 1.1
Ok, it's working like this, thanks .. i was thinking to the more complicated solution without thinking to easy one XD
Simone Margaritelli
:-) no problem.
N 1.1
Note that there is a problem with this code if you want to have any of your getopt options accept an argument. Then, getopt will cope if such an argument is in the following option (space between the option and its argument), but the loop will treat such an option as some_other_file, so it will be safer to use getopt's functionality, and let getopt do the parsing for you (details in my answer)
Michał Trybus
+3  A: 

getopt(_long) permutes the arguments in argv in such a way, that when there are no arguments it understands left (when it returns -1) all the parsed arguments are before the unparsed ones. So you can use the global variable optind, which getopt sets to the index of the first argument in argv, which it did not parse in order to find any additional arguments to your program. Supposing that except the arguments known by getopt there is one such some_other_file, the pseudocode would be:

while ((ret = getopt_long(argc, argv, ...)) != -1) {
    /* do something with ret */
}
if (optind >= argc) {
    /* error, no some_other_file */
} else {
    file_str = argv[optind];
    /* do something else */
}

This method can be extended to an arbitrary number of no-hyphen arguments, which are guaranteed to be all left in argv in order they were passed to the program, and all of them after any arguments understood by getopt, so a simple loop from optind to argc-1 can be used to list these unparsed arguments.

Michał Trybus
This is the better answer of the two, since the OP is already using `getopt`.
caf