以下是一段使用libpopt对命令行参数进行解析的程序。


//#include <stdio.h>
#include <stdlib.h>
#include <popt.h>


void usage(poptContext optCon, int exitcode, char *error, char *addl) {
   poptPrintUsage(optCon, stderr, 0);
   if (error) fprintf(stderr, "%s: %s\n", error, addl);
   exit(exitcode);
}

int main(int argc, char *argv[]) {
   int     c;            /* used for argument parsing */
   int     i = 0;        /* used for tracking options */
   int     speed = 0;    /* used in argument parsing to set speed */
   int     raw = 0;      /* raw mode? */
   int     j;
   char    buf[BUFSIZ+1];
   const char *portname;
   char * help = NULL;
   poptContext optCon;   /* context for parsing command-line options */

   

   //数组的每一个元素代表了一个选项。
   struct poptOption optionsTable[] = {

   { "bps", 'b', POPT_ARG_INT, &speed, 10,
               "signaling rate in bits-per-second", "BPS" },
   { "crnl", 'c', 0, 0, 'c',
       "expand cr characters to cr/lf sequences", NULL },
   { "hwflow", 'h', 0, 0, 'h',
       "use hardware (RTS/CTS) flow control", NULL },
   { "noflow", 'n', 0, 0, 'n',
       "use no flow control", NULL },
   { "raw", 'r', 0, &raw, 0,
               "don't perform any character conversions", NULL },
   { "swflow", 's', 0, 0, 's',
       "use software (XON/XOF) flow control", NULL } ,
   POPT_AUTOHELP
   { NULL, 0, 0, NULL, 0 }

   };


   //相当于初始化阶段

   optCon = poptGetContext(NULL, argc, (const char **)argv, optionsTable, 0);
 

  //没什么用处,只是在输出帮助信息时多了后面的字符串

  poptSetOtherOptionHelp(optCon, "[OPTIONS]* <port>");


   if (argc < 2) {
       poptPrintUsage(optCon, stderr, 0);
       exit(1);
   }

   //对-x进行逐个解析,例如-b选项,那么就需要将-b选项后面的值赋值给speed.

   //它在以下情况会选择返回:-x选项不清楚,返回值小于-1; optionsTable指定了返回值。

   while ((c = poptGetNextOpt(optCon)) >= 0) {
       switch (c) {

       case 'c':
           buf[i++] = 'c';
           break;
       case 'h':
           buf[i++] = 'h';
           break;
       case 's':
           buf[i++] = 's';
           break;
       case 'n':
           buf[i++] = 'n';
           break;
       }
   }


   //解析过以后,利用poptGetOptArg可查看某个选项的值。

   while((help = poptGetOptArg(optCon)) != NULL)
       printf("%d", help);


  //未被解析的字段会以类似argv的形式保存起来。
   portname = poptGetArg(optCon);
   if((portname == NULL) || !(poptPeekArg(optCon) == NULL))
       usage(optCon, 1, "Specify a single port", ".e.g., /dev/cua0");

   if (c < -1) {
       /* an error occurred during option processing */
       fprintf(stderr, "%s: %s\n",
               poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
               poptStrerror(c));
       return 1;
   }

   /* Print out options, portname chosen */

   printf("Options  chosen: ");
   for(j = 0; j < i ; j++)
       printf("-%c ", buf[j]);
   if(raw) printf("-r ");
   if(speed) printf("-b %d ", speed);
   printf("\nPortname chosen: %s\n", portname);

   poptFreeContext(optCon);
   exit(0);
}

poptContext poptGetContext(constchar* name,int argc,
                                               constchar** argv,
                                               conststruct poptOption * options,
                                               int flags);
void poptFreeContext(poptContext con);
void poptResetContext(poptContext con);
int poptGetNextOpt(poptContext con);
constchar* poptGetOptArg(poptContext con);
constchar* poptGetArg(poptContext con);
constchar* poptPeekArg(poptContext con);
constchar** poptGetArgs(poptContext con);
constchar*const poptStrerror(constint error);
constchar* poptBadOption(poptContext con,int flags);
int poptReadDefaultConfig(poptContext con,int flags);
int poptReadConfigFile(poptContext con,char* fn);
int poptAddAlias(poptContext con,struct poptAlias alias,
int flags);
int poptParseArgvString(char* s,int*  argcPtr,
constchar*** argvPtr);
int poptDupArgv(int argc,constchar** argv,int* argcPtr,
constchar*** argvPtr);
int poptStuffArgs(poptContext con,constchar** argv);


链接:http://www.cnblogs.com/qq78292959/archive/2012/06/05/2536455.html