Another option with similar levels of macro (ab)use is my "magic getopt" which lets you write code like this:
const char * ch;
while ((ch = GETOPT(argc, argv)) != NULL) {
GETOPT_SWITCH(ch) {
GETOPT_OPT("-a"):
aflag = 1;
break;
GETOPT_OPTARG("--bar"):
printf("bar: %s\n", optarg);
break;
GETOPT_OPTARG("-f"):
printf("foo: %s\n", optarg);
break;
GETOPT_MISSING_ARG:
printf("missing argument to %s\n", ch);
/* FALLTHROUGH */
GETOPT_DEFAULT:
usage();
}
}