I have this c program which use getopt_long
to parse -
and --
options, but when i parse --
options the optarg does not work for the program. how can i assing the optarg
value for the varibale if --
is parsed for the program.
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <getopt.h>
#include "file_handle.c"
//#include "songs.c"
#include "getoptions.c"
//Mix_Music *music = NULL;
int main(int argc, char *argv[])
{
//init();
int f = 0;
int d = 0;
char *file = NULL;
char *directory = NULL;
const struct option long_options[] = {
/*
{"verbose",no_argument,&verbose_flag,1}
*/
{"help", no_argument, 0, 'h'},
{"file", required_argument, &f, 'f'},
{"directory", required_argument, &d, 'd'},
{0, 0, 0, 0}
};
int opt;
if (argc <= 1)
{
fprintf(stderr, "No arguments provided!\nTry 'cplay --help' for more information.\n");
}
else
{
while ((opt = getopt_long(argc, argv, "d:f:h", long_options, NULL)) != -1)
{
printf("optarg %s\n",optarg);
switch(opt){
case 'h':
//print_help();
break;
case 'f':
puts("test f");
file = optarg;
break;
case 'd':
directory = optarg;
break;
default:
break;
}
}
}
if(f && d){
printf("OPTION -f, --file and -d, --directory are given\n");
printf("%s\n",directory);
int valid = 0;
char response;
while(!valid)
{
printf("Enter one option [f\\d]: ");
scanf(" %c",&response);
if(response == 'd' || response == 'f'){
valid = 1;
}
else
printf("Wrong Input given press f for single file and d for directory option\n");
}
}
printf("%d\n %d",f,d);
}
Re: "the switch statement is only checking for the -h or -d or -f options."
From the GNU manual:
When getopt_long encounters a long option, it takes actions based on the flag and val fields of the definition of that option. The option name may be abbreviated as long as the abbreviation is unique.
If flag is a null pointer, then getopt_long returns the contents of val to indicate which option it found.
If flag
(The third member of the struct option
) is NULL
, then getopt_long
returns the contents of val
(the fourth member of struct option
) to indicate which option it found.
So if the long option was --help
, and the corresponding val
member was assigned h
, then getopt_long
would return h
.
Some remarks:
if(f && d)
shouldn't be reached. Keep flags and check if the f
flag is already given before assigning true
to the d
flag.
bool f_flag = false;
bool d_flag = false;
Then check for the f_flag
:
...
case 'd':
if (f_flag) {
/* Both file and directory flags are
* present. Print usage message and exit.
*/
} else {
strcpy (directory, optarg);
break;
}
p
and q
, the statement:p = q;
doesn't copy the contents of the memory pointed to by q
to the contents of the memory pointed to by p
. It copies the pointer values, such that both p
and q
now point to the same memory, and any change to the memory via p
is reflected when q
is used.
So, given:
file = optarg;
and
directory = optarg;
these statements copies the pointer values, not the pointed to memory. This could be a problem if a subsequent operation modified argv
, because it would change the memory pointed to by optarg
and file
/ directory
too.
Instead, copy the memory to the pointers with strcpy()
:
strcpy (file, optarg);
strcpy (directory, optarg);