So, I have next code:
#include<unistd.h>
#include<getopt.h>
#include<getopt.h>
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>
// #include"main.hpp"
// #include"functions.cpp"
int main(int argc, char** argv) {
opterr = 0;
int f_verbose = false;
int option_index = 0;
static struct option long_options[] =
{
{"file", required_argument, NULL, 'f'},
{"verbose", no_argument, NULL, 'v'},
{"help", no_argument, NULL, 'h'},
{"version", no_argument, NULL, 1},
{NULL, 0, NULL, 0},
};
int arg;
char* file_path = NULL;
while( -1 != (arg = getopt_long(argc, argv, ":f:hv", long_options, &option_index)) ) {
switch(arg) {
// case 0: // long options
// if (long_options[option_index].flag != 0)
// break;
case ':':
fprintf(stderr, "No argument(s) provided for '%s' option.\n", argv[optopt]);
// read_help(*argv);
exit(EXIT_FAILURE);
case '?':
fprintf(stderr, "Unknown option: '%s'.\n", argv[optopt]);
// read_help(*argv);
exit(EXIT_FAILURE);
case 'f':
errno = 0;
file_path = (char*)malloc(sizeof(*optarg)*(strlen(optarg) + 1));
if (file_path == NULL) {
fprintf(stderr, "Could not allocate memory: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
break;
case 'v':
f_verbose = true;
break;
case 'h':
printf("Usage: %s -f filename [-v | --verbose] [-h | --help]\n"
"\n"
"Avaliable options:\n"
" -f, --file <filename>\n"
" Get lines coordinates from <filename>.\n"
" -v, --verbose\n"
" Print execution time\n"
" -h, --help\n"
" Print help message\n"
" --version\n"
" Print version.\n"
"\n"
"Program purpose:\n"
"You should pass filename of file, first\n"
"two strings containing two numbers of 2D\n"
"plane coordinates of lines ends in each.\n"
"Program have to calculate and print lines\n"
"interception coordinates, if there is some.\n",
*argv);
exit(EXIT_SUCCESS);
case 1: // --version
printf("v1.0, mod 3, NAU, Vladyslav Rehan, 2023.\n");
exit(EXIT_SUCCESS);
default:
printf("ENTERED DEfAULT\n");
abort();
}
}
printf("END\n");
}
When I compile it and pass bad option, I get segmentation fault or Unknown option error provided by getup_long
I guess:
➜ Mod_1 g++ main.cpp
➜ Mod_1 ./a.out --unknown
Unknown option: './a.out'.
➜ Mod_1 ./a.out -a
[1] 18507 segmentation fault ./a.out -a
➜ Mod_1 ./a.out -c
[1] 18517 segmentation fault ./a.out -c
➜ Mod_1 ./a.out --what
Unknown option: './a.out'.
➜ Mod_1 ./a.out -v
END
➜ Mod_1 ./a.out --version
v1.0, mod 3, NAU, Vladyslav Rehan, 2023.
➜ Mod_1 ./a.out --v
Unknown option: './a.out'.
➜ Mod_1 what is happening
Why I get Unknown option: './a.out'.
if I have set opterr = 0;
?
Why there is segmentation fault?
And, I do now about optind-1
trick, but it wont work properly with ./a.out -ac
for example:
➜ Mod_1 ./a.out -ac
Unknown option: './a.out'.
Again some mysterious error message appears.
I have already reviewed GNU Clib doc ten times, it says that getopt_long
works the same as getopt
so opterr = 0;
and int optopt
should make sense. Or I am misunderstanding something? How to detect type (long option or short option) of bad option?
This was solved as:
#include<unistd.h>
#include<getopt.h>
#include<getopt.h>
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<string.h>
// #include"main.hpp"
// #include"functions.cpp"
int main(int argc, char** argv) {
opterr = 0;
int f_verbose = false;
int option_index = 0;
static struct option long_options[] =
{
{"file", required_argument, NULL, 'f'},
{"verbose", no_argument, NULL, 'v'},
{"help", no_argument, NULL, 'h'},
{"version", no_argument, NULL, 1},
{NULL, 0, NULL, 0},
};
int arg;
char* file_path = NULL;
while( -1 != (arg = getopt_long(argc, argv, ":f:hv", long_options, &option_index)) ) {
switch(arg) {
// case 0: // long options
// if (long_options[option_index].flag != 0)
// break;
case ':':
if (long_options[option_index].has_arg == required_argument)
fprintf(stderr, "No argument(s) provided for '--%s' long option.\n", long_options[option_index].name);
else
fprintf(stderr, "No argument(s) provided for '-%c' option.\n", optopt);
// read_help(*argv);
exit(EXIT_FAILURE);
case '?':
if (optopt == 0)
fprintf(stderr, "Unknown long option: '%s'.\n", argv[optind-1]);
else
fprintf(stderr, "Unknown option: '-%c'.\n", optopt);
// read_help(*argv);
exit(EXIT_FAILURE);
case 'f':
errno = 0;
file_path = (char*)malloc(sizeof(*optarg)*(strlen(optarg) + 1));
if (file_path == NULL) {
fprintf(stderr, "Could not allocate memory: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
break;
case 'v':
f_verbose = true;
break;
case 'h':
printf("Usage: %s -f filename [-v | --verbose] [-h | --help] [--version]\n"
"\n"
"Avaliable options:\n"
" -f, --file <filename>\n"
" Get lines coordinates from <filename>.\n"
" -v, --verbose\n"
" Print execution time\n"
" -h, --help\n"
" Print help message\n"
" --version\n"
" Print version.\n"
"\n"
"Program purpose:\n"
"You should pass filename of file, first\n"
"two strings containing two numbers of 2D\n"
"plane coordinates of lines ends in each.\n"
"Program have to calculate and print lines\n"
"interception coordinates, if there is some.\n",
*argv);
exit(EXIT_SUCCESS);
case 1: // --version
printf("v1.0, mod 3, NAU, Vladyslav Rehan, 2023.\n");
exit(EXIT_SUCCESS);
default:
printf("ENCOUNTERED deFAULT\n");
abort();
}
}
printf("END\n");
}