原创 getopt_long及其使用(ZZ)

2009-1-2 14:58 3570 10 8 分类: MCU/ 嵌入式
選自:
http://hi.baidu.com/harite/blog/item/2ad9aaec43f87b3d2697913d.html

  Linux系统下,需要大量的命令行选项,如果自己手动解析他们的话实在是有违软件复用的思想,不过还好,GNU C library留给我们一个解析命令行的接口(X/Open规范),好好使用它可以使你的程序改观不少。

使用getopt_long()需要引入头文件


#include <getopt.h>


     现在我们使用一个例子来说明它的使用。


一个应用程序需要如下的短选项和长选项。




      短选项               长选项                           作用


      -h                      --help                           输出程序命令行参数说明然后退出

      -o filename        --output filename      给定输出文件名

      -v                      --version                       显示程序当前版本后退后


为了使用getopt_long函数,我们需要先确定两个结构:


1.一个字符串,包括所需要的短选项字符,如果选项后有参数,字符后加一个":"符号。本例中,这个字符串应该为"ho:v"。(因为-o后面有参数filename,所以字符后面要加":")


2.一个包含长选项字符串的结构体数组,每一个结构体包含4个域,第一个域为长选项字符串,第二个域是一个标识,只能为0或1,分别代表没有、有。
第三个域永远为NULL。第四个域为对应的短选项字符串。结构体数组的最后一个元素全部为NULL和0,标识结束。在本例中,它应该像一下的样子:


     const struct option long_options[] = {

         { "help",        0, NULL, 'h' },

         { "output",      1, NULL, 'o' },

         { "version", 0, NULL, 'v' },

         { NULL,          0, NULL, 0}

      };


调用时需要把main的两个参数argc和argv以及上述两个数据结构传给getopt_long。

每次调用getopt_long,它会解析一个符号,返回相应的短选项字符,如果解析完毕返回-1。所以需要使用一个循环来处理所有的参数,而相应的循环
里会使用switch语句进行选择。如果getopt_long遇到一个无效的选项字符,它会打印一个错误消息并且返回'?',很多程序会打印出帮助信息
并且中止运行;当getopt_long解析到一个长选项并且发现后面没有参数则返回':',表示缺乏参数。当处理一个参数时,全局变量optarg指向
下一个要处理的变量。当getopt_long处理完所有的选项后,全局变量optind指向第一个未知的选项索引。


这一个例子代码为下:



//编译使用gcc -o getopt_long getopt_long.c

#include <getopt.h>

#include <stdio.h>

#include <stdlib.h>


/*程序的名字*/

const char* program_name;


/* 打印程序参数 */

void print_usage (FILE* stream, int exit_code)

{

fprintf (stream, "Usage: %s options [ inputfile ... ]\n", program_name);

fprintf (stream, " -h --help                       显示这个帮助信息.\n"

                             " -o --output filename 将输出定位到文件.\n"

                             " -v --version                  打印版本信息.\n");

exit (exit_code);

}




/* 主程序 */

int main (int argc, char* argv[])

{

int next_option;//下一个要处理的参数符号

int haveargv = 0;//是否有我们要的正确参数,一个标识

           

/* 包含短选项字符的字符串,注意这里的‘:’ */

          

const char* const short_options = "ho:v";

              

/* 标识长选项和对应的短选项的数组 */

              

const struct option long_options[] = {

                   { "help",        0, NULL, 'h' },

                   { "output",      1, NULL, 'o' },

                   { "version", 0, NULL, 'v' },

                   { NULL,         0, NULL, 0     }};//最后一个元素标识为NULL

                    

    /* 此参数用于承放指定的参数,默认为空 */

const char* output_filename = NULL;

/* 一个标志,是否显示版本号 */

int verbose = 0;


/* argv[0]始终指向可执行的文件文件名 */

                             

program_name = argv[0];

    

do

{

    next_option = getopt_long (argc, argv, short_options, long_options, NULL);

    switch (next_option)

    {

       case 'h':     /* -h or --help */    

           haveargv = 1;

           print_usage (stdout, 0);

       case 'o':     /* -o or --output */

           /* 此时optarg指向--output后的filename */

          output_filename = optarg;

          haveargv = 1;

          break;

       case 'v':     /* -v or    --version */

          verbose = 1;

          haveargv = 1;

          break;

       case ':':     /* 缺乏长选项内容 */

          break;


       case '?':     /* 出现一个未指定的参数*/

          print_usage (stderr, 1);

       case -1:      /* 处理完毕后返回-1 */

             if (!haveargv)

             {

                   print_usage (stderr, 1);

             }

         break;

     default:      /* 未指定的参数出现,出错处理 */

         print_usage (stderr, 1);

                                  break;

    }

} while (next_option !=-1);

                            

if (verbose)

{

    int i;

    for (i = optind; i < argc; ++i)

    printf ("Argument: %s\n", argv);

}                           

                        

return 0;

}
PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
10
关闭 站长推荐上一条 /3 下一条