24.6 getopt()、getopt_long()、getopt_long_only()是何用法 Q: 能给一个getopt()的例子吗 A: 小四 1999-04-05 17:02 -------------------------------------------------------------------------- /* * For x86/Linux * gcc -Wall -pipe -O3 -s -o getopt_test getopt_test.c */ #include #include #include #include #include #define VERSION "1.00 1999-04-05 17:02" static void usage ( char *arg ) { fprintf ( stderr, "Usage: %s [-h] [-v] [-i intvar] [-s strvar]\n", arg ); exit( EXIT_FAILURE ); } /* end of usage */ int main ( int argc, char * argv[] ) { int ret = EXIT_FAILURE; int c; unsigned int intvar = 0; char *strvar = NULL; if ( 1 == argc ) { usage( argv[0] ); } /* * don't want getopt() writing to stderr */ opterr = 0; /* * getopt()第三形参最前面如果有冒号,就不会出现illegal option错误信息。 * 不过,如果指定了"opterr = 0",有无这个前导冒号都无所谓了。 */ while ( EOF != ( c = getopt( argc, argv, ":hi:s:v" ) ) ) { switch ( c ) { case 'i': intvar = ( unsigned int )strtoul( optarg, NULL, 0 ); break; case 's': strvar = optarg; break; case 'v': printf( "%s ver "VERSION"\n", argv[0] ); return( EXIT_SUCCESS ); case 'h': case '?': default : usage( argv[0] ); break; } /* end of switch */ } /* end of while */ argc -= optind; argv += optind; printf ( "intvar = %u\n" "strvar = %s\n", intvar, NULL == strvar ? "(null)" : strvar ); ret = EXIT_SUCCESS; return( ret ); } /* end of main */ #if 0 $ ./getopt_test -h Usage: ./getopt_test [-h] [-v] [-i intvar] [-s strvar] $ ./getopt_test -i 1314 -s scz intvar = 1314 strvar = scz $ ./getopt_test -v ./getopt_test ver 1.00 1999-04-05 17:02 #endif -------------------------------------------------------------------------- Q: 现在会用getopt()了,但如何支持"--parami intvar --params strvar"呢 A: 小四 2001-12-17 15:30 这需要用到getopt_long(),但这不是一个具有良好可移植性的函数。 -------------------------------------------------------------------------- /* * For x86/Linux * gcc -Wall -pipe -O3 -s -o getopt_long_test getopt_long_test.c */ #include #include #include #include #include /* * 为了使用getopt_long(),必须有如下两行内容 */ #define _GNU_SOURCE #include #define VERSION "1.00 2001-12-17 15:30" /* * 不要与短选项所用的字符相同! */ #define LONGOPTIONCHAR '*' static void usage ( char *arg ) { fprintf ( stderr, "Usage: %s [-h] [--ver] [--parami intvar] [-params strvar]\n", arg ); exit( EXIT_FAILURE ); } /* end of usage */ int main ( int argc, char * argv[] ) { int ret = EXIT_FAILURE; int c; unsigned int intvar = 0; char *strvar = NULL; struct option longOption[] = { { "ver", 0, NULL, LONGOPTIONCHAR }, { "parami", 1, NULL, LONGOPTIONCHAR }, { "params", 1, NULL, LONGOPTIONCHAR }, { NULL, 0, NULL, 0 } }; int longOptionIndex = 0; if ( 1 == argc ) { usage( argv[0] ); } /* * don't want getopt() writing to stderr */ opterr = 0; while ( EOF != ( c = getopt_long( argc, argv, ":h", longOption, &longOptionIndex ) ) ) { switch ( c ) { case LONGOPTIONCHAR: if ( optarg ) { switch ( longOptionIndex ) { case 1: intvar = ( unsigned int )strtoul( optarg, NULL, 0 ); break; case 2: strvar = optarg; break; default: break; } /* end of switch */ } else { switch ( longOptionIndex ) { /* * longOption[]的下标 */ case 0: printf( "%s ver "VERSION"\n", argv[0] ); return( EXIT_SUCCESS ); default: break; } /* end of switch */ } break; case 'h': case '?': default : usage( argv[0] ); break; } /* end of switch */ } /* end of while */ argc -= optind; argv += optind; printf ( "intvar = %u\n" "strvar = %s\n", intvar, NULL == strvar ? "(null)" : strvar ); ret = EXIT_SUCCESS; return( ret ); } /* end of main */ #if 0 $ ./getopt_long_test -h Usage: ./getopt_long_test [-h] [--ver] [--parami intvar] [-params strvar] $ ./getopt_long_test --parami 1314 --params scz intvar = 1314 strvar = scz $ ./getopt_long_test --ver ./getopt_long_test ver 1.00 2001-12-17 15:30 #endif -------------------------------------------------------------------------- Q: 那getopt_long_only()与getopt_long()的区别是什么 A: 小四 2005-05-09 10:48 getopt_long_only()的行为与getopt_long()非常类似,但不限于用'--'引入长选项, '-'亦可引入长选项。当'-'引入的选项不匹配任何长选项时,继续进行短选项匹配。 再次提醒,getopt_long_only()与getopt_long()一样,不具有良好可移植性。 -------------------------------------------------------------------------- /* * For x86/Linux * gcc -Wall -pipe -O3 -s -o getopt_long_only_test getopt_long_only_test.c */ #include #include #include #include #include /* * 为了使用getopt_long_only(),必须有如下两行内容 */ #define _GNU_SOURCE #include #define VERSION "1.00 2005-05-09 10:48" /* * 不要与短选项所用的字符相同!这次用空格符,更可靠些。 */ #define LONGOPTIONCHAR ' ' static void usage ( char *arg ) { fprintf ( stderr, "Usage: %s [-h] [--v] [-i intvar] [--s strvar]\n", arg ); exit( EXIT_FAILURE ); } /* end of usage */ int main ( int argc, char * argv[] ) { int ret = EXIT_FAILURE; int c; unsigned int intvar = 0; char *strvar = NULL; struct option longOption[] = { { "v", 0, NULL, LONGOPTIONCHAR }, { "s", 1, NULL, LONGOPTIONCHAR }, { NULL, 0, NULL, 0 } }; int longOptionIndex = 0; if ( 1 == argc ) { usage( argv[0] ); } /* * don't want getopt() writing to stderr */ opterr = 0; while ( EOF != ( c = getopt_long_only( argc, argv, ":hi:", longOption, &longOptionIndex ) ) ) { switch ( c ) { case LONGOPTIONCHAR: if ( optarg ) { switch ( longOptionIndex ) { case 1: strvar = optarg; break; default: break; } /* end of switch */ } else { switch ( longOptionIndex ) { /* * longOption[]的下标 */ case 0: printf( "%s ver "VERSION"\n", argv[0] ); return( EXIT_SUCCESS ); default: break; } /* end of switch */ } break; case 'i': intvar = ( unsigned int )strtoul( optarg, NULL, 0 ); break; case 'h': case '?': default : usage( argv[0] ); break; } /* end of switch */ } /* end of while */ argc -= optind; argv += optind; printf ( "intvar = %u\n" "strvar = %s\n", intvar, NULL == strvar ? "(null)" : strvar ); ret = EXIT_SUCCESS; return( ret ); } /* end of main */ #if 0 $ ./getopt_long_only_test -h Usage: ./getopt_long_only_test [-h] [--v] [-i intvar] [--s strvar] $ ./getopt_long_only_test --v ./getopt_long_only_test ver 1.00 2005-05-09 10:48 $ ./getopt_long_only_test -v ./getopt_long_only_test ver 1.00 2005-05-09 10:48 $ ./getopt_long_only_test -i 1314 -s scz intvar = 1314 strvar = scz #endif --------------------------------------------------------------------------