I'm trying to parse two options in a C program.
The program is called like this:
./a.out [OPTIONS] [DIRECTORY 1] [DIRECTORY 2]
The program syncs two directories and has two options. (-r)
for recursive syncing (folder inside folder), and (-n)
to copy file from local to remote in case it doesn't exist in remote.
Options are:
-r : recursive
-n : copy file if it doesn't exist in remote folder
So calling:
./a.out -r D1 D2
would recursively sync all files and directories from D1
to D2
. Files presents in D1
and not present in D2
are ignored.
And calling:
./a.cout -rn D1 D2
would do the same thing but files present in D1
and not present in D2
are copied to D2
.
The problem is that calling ./a.out -rn
is not the same as calling ./a.out -nr
and ./a.out -r -n
is not working neither because (-n)
is not D1
.
Here is how I implement the main.
int main(int argc, char** argv) {
int next_option = 0;
const char* const short_options = "hrn:";
const struct option long_options[] = {
{ "help", 0, NULL, 'h' },
{ "recursive", 1, NULL, 'r' },
{ "new", 1, NULL, 'n' },
{ NULL, 0, NULL, 0 }
};
int recursive = 0;
int new = 0;
do {
next_option = getopt_long(argc, argv, short_options, long_options, NULL);
switch(next_option) {
case 'r':
recursive = 1;
break;
case 'n':
new = 1;
break;
case 'h':
print_help();
return 0;
case -1:
break;
default:
print_help();
return -1;
}
} while(next_option != -1);
sync(argv[2], argv[3], recursive, new);
return EXIT_SUCCESS;
}
You have two (potential) problems here:
You have a stray :
in your short option string. This makes -n
take an option that swallows any following r
. You also have the long options set to take mandatory arguments.
You've hard coded the argument numbers in an inflexible way, and you don't test that they exist.
Try this:
int main(int argc, char** argv) {
int next_option = 0;
const char* const short_options = "hrn";
extern int optind;
const struct option long_options[] = {
{ "help", no_argument, NULL, 'h' },
{ "recursive", no_argument, NULL, 'r' },
{ "new", no_argument, NULL, 'n' },
{ NULL, no_argument, NULL, 0 }
};
int recursive = 0;
int new = 0;
do {
next_option = getopt_long(argc, argv, short_options, long_options, NULL);
switch(next_option) {
case 'r':
recursive = 1;
break;
case 'n':
new = 1;
break;
case 'h':
print_help();
return 0;
case -1:
break;
default:
print_help();
return -1;
}
} while(next_option != -1);
if (optind + 1 >= argc)
return -1;
sync(argv[optind], argv[optind+1], recursive, new);
return EXIT_SUCCESS;
}