分享

getopt

 昵称6056135 2011-11-04
 
    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,标识结束。在本例中,它应该像一下的样子:

  1. const struct option long_options[] = {  
  2.     { "help",        0, NULL, 'h' },  
  3.     { "output",      1, NULL, 'o' },  
  4.     { "version", 0, NULL, 'v' },  
  5.     { NULL,          0, NULL, 0}  
  6.  };  


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

这一个例子代码为下:

  1. //编译使用gcc -o getopt_long getopt_long.c   
  2. #include <getopt.h>   
  3. #include <stdio.h>   
  4. #include <stdlib.h>   
  5.   
  6. /*程序的名字*/  
  7. const char* program_name;  
  8.   
  9. /* 打印程序参数 */  
  10. void print_usage (FILE* stream, int exit_code)  
  11. {  
  12. fprintf (stream, "Usage: %s options [ inputfile ... ]\n", program_name);  
  13. fprintf (stream, " -h --help                       显示这个帮助信息.\n"  
  14.                              " -o --output filename 将输出定位到文件.\n"  
  15.                              " -v --version                  打印版本信息.\n");  
  16. exit (exit_code);  
  17. }  
  18.   
  19.   
  20. /* 主程序 */  
  21. int main (int argc, char* argv[])  
  22. {  
  23. int next_option;//下一个要处理的参数符号   
  24. int haveargv = 0;//是否有我们要的正确参数,一个标识   
  25.              
  26. /* 包含短选项字符的字符串,注意这里的‘:’ */  
  27.             
  28. const charconst short_options = "ho:v";  
  29.                 
  30. /* 标识长选项和对应的短选项的数组 */  
  31.                 
  32. const struct option long_options[] = {  
  33.                    { "help",        0, NULL, 'h' },  
  34.                    { "output",      1, NULL, 'o' },  
  35.                    { "version", 0, NULL, 'v' },  
  36.                    { NULL,         0, NULL, 0     }};//最后一个元素标识为NULL   
  37.                       
  38.     /* 此参数用于承放指定的参数,默认为空 */  
  39. const char* output_filename = NULL;  
  40. /* 一个标志,是否显示版本号 */  
  41. int verbose = 0;  
  42. /* argv[0]始终指向可执行的文件文件名 */  
  43.                                
  44. program_name = argv[0];  
  45.       
  46. do  
  47. {  
  48.     next_option = getopt_long (argc, argv, short_options, long_options, NULL);  
  49.     switch (next_option)  
  50.     {  
  51.      case 'h':     /* -h or --help */      
  52.        haveargv = 1;  
  53.        print_usage (stdout, 0);  
  54.      case 'o':     /* -o or --output */  
  55.          /* 此时optarg指向--output后的filename */  
  56.       output_filename = optarg;  
  57.       haveargv = 1;  
  58.       break;  
  59.      case 'v':     /* -v or    --version */  
  60.       verbose = 1;  
  61.       haveargv = 1;  
  62.       break;  
  63.      case ':':     /* 缺乏长选项内容 */  
  64.       break;  
  65.      case '?':     /* 出现一个未指定的参数*/  
  66.       print_usage (stderr, 1);  
  67.      case -1:      /* 处理完毕后返回-1 */  
  68.              if (!haveargv)  
  69.              {  
  70.                    print_usage (stderr, 1);  
  71.              }  
  72.       break;  
  73.      default:      /* 未指定的参数出现,出错处理 */  
  74.       print_usage (stderr, 1);  
  75.                                   break;  
  76.     }  
  77. }while (next_option !=-1);  
  78.                               
  79. if (verbose)  
  80. {  
  81.     int i;  
  82.     for (i = optind; i < argc; ++i)  
  83.     printf ("Argument: %s\n", argv[i]);  
  84. }                             
  85.                           
  86. return 0;  
  87. }  

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多