I am using getopt to parse command line arguments and my issue is that some of my options have options. My project is to test different backend implementations of maps and the -b flag specifies which implementation to use. Most of the options are straight forward but for the backends that use hash tables (chained and open) there is an additional -number that can be added to the end to specify the load factor. So it would be -b chained-0.75
.
My idea is that I would take the substring from 8 to the end (or 5 for the "open" option) because that would ignore the "chained-" part of the string and then use atof() to convert it to a double and then declare my map. I believe optarg is a char array (?) and I keep running into type mismatch errors even though I have tried std::string str(optarg);
I also don't know what to write in place of else if (strcasecmp(optarg, "chained") == 0)
because there could be any number at the end of it. So right now when I do -b chained-0.75
it calls the usage function.
Here is what I have so far:
while ((c = getopt(argc, argv, "hb:n:p:")) != -1) {
switch (c) {
case 'b':
if (strcasecmp(optarg, "unsorted") == 0) {
map = new UnsortedMap();
} else if (strcasecmp(optarg, "sorted") == 0) {
map = new SortedMap();
} else if (strcasecmp(optarg, "bst") == 0) {
map = new BSTMap();
} else if (strcasecmp(optarg, "unordered") == 0) {
map = new UnorderedMap();
} else if (strcasecmp(optarg, "chained") == 0) {
double load_factor;
std::string str(optarg);
std::string ld_str = str.substr(8, str.length()-1);
load_factor = atof(ld_str);
map = new ChainedMap(load_factor);
} else if (strcasecmp(optarg, "open") == 0) {
map = new OpenMap();
} else {
usage(1);
}
break;
Any hints or ideas would be appreciated!
strcasecmp()
is an exact match comparison function, this strcasecmp()
will obviously not match "chained-0.75". The only thing that strcasecmp()
will match against the string "chained" is "chained", not "chained-0.75", not "changed-foobar", not "chained-anything".
The right function is strncasecmp
:
} else if (strncasecmp(optarg, "chained-", 8) == 0) {
Note that you're comparing against "chained-", and not just "chained". A few moments' of thinking should make it clear why.
The existing code also fails to take into account the possibility that the string after "chained-" is not a number, since atof()
does not handle parsing errors. If you need to be able to detect and handle an error here, use strtod()
instead of atof()
.