Parsing on my own:
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char* filepath;
bool myflag;
int myvalue;
} CliArgs;
static inline void error(const char* message) {
fprintf(stderr, "%s\n", message);
exit(1);
}
CliArgs parse(int argc, char** argv) {
CliArgs cli_args = { .filepath = 0, .myflag = false, .myvalue = 0 };
if (argc == 1)
error("No argument was passed.");
for (int i = 1; i < argc; ++i) {
if (!strcmp(argv[i], "--myflag")) {
cli_args.myflag = true;
continue;
}
if (!strcmp(argv[i], "--myvalue")) {
++i;
if (i == argc)
error("No value passed for --myvalue.");
char* str_end;
cli_args.myvalue = strtol(argv[i], &str_end, 10);
if (*str_end)
error("Invalid value for --myvalue.");
continue;
}
if (cli_args.filepath)
error("Only a single filepath can be given.");
else
cli_args.filepath = argv[i];
}
if (!cli_args.filepath)
error("No filepath was passed.");
return cli_args;
}
int main(int argc, char** argv) {
CliArgs cli_args = parse(argc, argv);
printf("%s was called:\n", argv[0]);
printf(
"%s is the filepath, myflag is %s and myvalue is %i.\n",
cli_args.filepath,
cli_args.myflag ? "true" : "false",
cli_args.myvalue
);
return 0;
}
Running it:
$ gcc cli_args.c -o cli_args
$ ./cli_args
No argument was passed.
$ ./cli_args foo.txt
./cli_args was called:
foo.txt is the filepath, myflag is false and myvalue is 0.
$ ./cli_args foo.txt --myvalue
No value passed for --myvalue.
$ ./cli_args foo.txt --myvalue bar
Invalid value for --myvalue.
$ ./cli_args foo.txt --myvalue 123
./cli_args was called:
foo.txt is the filepath, myflag is false and myvalue is 123.
$ ./cli_args foo.txt --myvalue 123 --myflag
./cli_args was called:
foo.txt is the filepath, myflag is true and myvalue is 123.