getopt
getopt関数は「そういうのがある」というぐらいの認識で、実は今まで使ったことがなかったんだけど、今自分が構想を練っているアプリケーションで、 コマンドラインオプションの解析が必要になりそうなので、使ってみた。例えば、以下のような形式のコマンドを解釈したいとする。
cmd command [option] args
解析したいのは[option]以降なので、getoptにはmainのargvをそのまま渡すのではなく、1個ずらしたものを渡す。以下、C++のコード。ほとんどCだけど。
#include <cstdio> #include <cstring> #include <cstdlib> #include <unistd.h> void usage(); int dispatchCommand(char *command); void dispatchOptions(int argc, char *argv[]); int dispatchCommand (char *command) { int len; int commandType = 0; len = strlen(command); if (strncmp(command, "command1", len) == 0) { commandType = 1; } else if (strncmp(command, "command2", len) == 0) { commandType = 2; } else { printf("command is invalid.\n"); } return commandType; } void dispatchOptions (int argc, char *argv[]) { int ch; extern char* optarg; extern int optind, opterr; while ((ch = getopt(argc, argv, "rn:")) != -1){ switch (ch){ case 'r': printf("Option r is selected.\n"); break; case 'n': printf("Option n is selected.\n"); printf("Value = %d\n",atoi(optarg)); break; default: usage(); } } argc -= optind; argv += optind; printf("arg1 = %s\n", argv[0]); printf("arg2 = %s\n", argv[1]); } void usage(void){ fprintf(stderr, "Usage: cmd command [option] args\n"); fprintf(stderr, " -r : option r\n"); fprintf(stderr, " -n # : option b (# is a number)\n"); exit(1); } int main(int argc,char *argv[]){ if (argc < 2) { printf("few argument\n"); return 0; } printf("commandNumber:%d\n", dispatchCommand(argv[1])); if (argc < 3) { printf("few argument\n"); return 0; } char **optargs; optargs = ++argv; dispatchOptions(--argc, optargs); return 0; }
う〜ん、オプションで使えるのは一文字なのか。
getopt_longって関数だと--filesみたいなことができるみたいだけど、
それはまた今度。いくつかのオープンソースソフトウェアのソースコードを見てみたけど、
生のgetopt使ってるのは案外少ないなあ。中にはif-elseだけで全部処理してるのもあったし。
実行結果
narazuya@bokko% g++ -o getopt_test test.cpp narazuya@bokko% ./getopt_test command1 -r 10 20 commandNumber:1 Option r is selected. arg1 = 10 arg2 = 20 narazuya@bokko% ./getopt_test command1 -n 10 20 commandNumber:1 Option n is selected. Value = 10 arg1 = 20 arg2 = (null) narazuya@bokko% ./getopt_test command2 -r 10 20 commandNumber:2 Option r is selected. arg1 = 10 arg2 = 20 narazuya@bokko% ./getopt_test command2 -n 10 20 commandNumber:2 Option n is selected. Value = 10 arg1 = 20 arg2 = (null) narazuya@bokko%