Chinaunix首页 | 论坛 | 博客
  • 博客访问: 9140454
  • 博文数量: 1725
  • 博客积分: 12961
  • 博客等级: 上将
  • 技术积分: 19840
  • 用 户 组: 普通用户
  • 注册时间: 2009-01-09 11:25
个人简介

偷得浮生半桶水(半日闲), 好记性不如抄下来(烂笔头). 信息爆炸的时代, 学习是一项持续的工作.

文章分类

全部博文(1725)

文章存档

2024年(1)

2023年(26)

2022年(112)

2021年(217)

2020年(157)

2019年(192)

2018年(81)

2017年(78)

2016年(70)

2015年(52)

2014年(40)

2013年(51)

2012年(85)

2011年(45)

2010年(231)

2009年(287)

分类: Android平台

2018-02-01 14:59:10

学习库的最好源码就是从其 utils 源代码学起.
apt-get download alsa-utils. 
先从 aplay/arecord 说起.  cat aplay/aplay.c

1. 命令行选项.
    一般情况下, 命令都会通过命令行导入一下运行时参数 (以 -Type [param]形式), 此时在程序中可以使用 如下类似代码
    简易方式.
  1. #include <unistd.h>
  2. int getopt(int argc, char * const *argv, const char *optstring);
  3. extern char *optarg;
  4. extern int optind, opterr, optopt;

  5. 选项在 argv 中以 "-" 为前导,与后续参数之间可带可不带空格连接
  6. getopt是一个需要循环调用的函数,每次返回一个找到的参数, 找不到时返回 -1

  7. 每个选项拥有optind变量(从1开始),代表要处理选项在argv中的位置, 此变量可以修改,以便于控制getopt的循环扫描。

  8. optstring 为参数格式化串
  9.     如果后面带有符号:, 则说明此选项后需要额外带有参数, 用 optarg 变量代表此附带参数。 
  10.     如果两个::则代表参数为可选参数,可加可不加, 有时optarg代表参数,无时为NULL。 

  11. 当命令行中 出现了 optstring 不存在的选项时,不存在选项存储在optopt变量中,getopt函数返回 ‘?’同时在标准错误中输出信息(如果设置了opterr=0,则不会输出).

  12. 范例: 
  13. ########################################################################################
  14. #define _XOPEN_SOURCE 
    #include
    #include
    #include

    int main(int argc, char *argv[])
    {
    int opt;

    opterr = 0;  /* getopt 出现不可识别选项时不要打印错误信息. */         
    while ((opt = getopt(argc, argv, "nt:b::")) != -1)  
    {
    switch (opt) {
    case 'n':
    fprintf(stderr, "option [-n] found.\n");
    break;
    case 'b':
    fprintf(stderr, "option [-b] found. value = [%s]\n", optarg);
    break;      
    case 't':    
    fprintf(stderr, "option [-t] found. value = [%s]\n", optarg);
    break; 
    default: /* '?' or ':' */
    fprintf(stderr, "err-opt[%c] found. value = [%s]\n", opt, optarg);
    }
    }

    if (optind >= argc) {
    fprintf(stderr, "Expected argument after options\n");
    exit(EXIT_FAILURE);
    }

    exit(EXIT_SUCCESS);
    }

    ### 输出 ###
    ### -n -a aa -bbb -t 5 
    option [-n] found.
    err-opt[?] found. value = [(null)]  ### -a aaa
    option [-b] found. value = [bb]   ### b:: 情况下, 参数一定要紧跟着选项
    option [-t] found. value = [5]
      
还有另外一种方式

  1. #define _GNU_SOURCE

  2. int getopt_long(int argc, char * const argv[],
  3.                   const char *optstring,
  4.                   const struct option *longopts, int *longindex);

  5. int getopt_long_only(int argc, char * const argv[],
  6.                   const char *optstring,
  7.                   const struct option *longopts, int *longindex)


    getopt_longgetopt一样, 但他还支持 -- 的选项.
    getopt_long_only仅支持--, 其optstring应该为空""
    长格式为 --opt[{ |=}arg   ] 即有参数是需以空格或者=为分割,后带参数的格式.

        struct option {
               const char *name;        //选项名称
               int         has_arg;    //常量 no_argument/0, required_argument/1, optional_argument/2 
               int        *flag; //指定函数返回, 一般情况下设置为NULL. 当 flag==NULL,则返回val. 其他情况返回0, 当选项存在时 flag指向要设置成 val 的指针.  
               int         val; //函数返回,或者要设置到flags指针的值.
           };

        longopts 的最后一项必须是0填充, 作为所有选项的结束.
        longindex != NULL 时, 他指向 longopts 其中的一项.
        函数返回同 getopt, 错误是返回 -1, 遇到不认识的返回"?", 否则返回 0 或者val.

范例

点击(此处)折叠或打开

  1. #include <stdio.h> /* for printf */
  2. #include <stdlib.h> /* for exit */
  3. #include <getopt.h>

  4. static const char short_options[] = "nlLD:qt:c:f:r:d:MNF:A:R:T:B:vV:IPC" //短格式 - 打头
  5. static const struct option long_options[] = {
  6.         {"list-devnames"/* name */, 0 /*是否有参数*/, 0 /* 返回类型 */, 'n' /*找到name时函数返回值*/},
  7.         {"list-devices", 0, 0, 'l'}, //长格式 -- + name 大头
  8.         {"list-pcms", 0, 0, 'L'}, //返回值一般和短格式的对应, 这样就可以长短格式混用.
  9.         {"device", 1, 0, 'D'},
  10.         {"quiet", 0, 0, 'q'},
  11.         {"file-type", 1, 0, 't'},
  12.         {"channels", 1, 0, 'c'},
  13.         {"format", 1, 0, 'f'},
  14.         {"rate", 1, 0, 'r'},
  15.         {"duration", 1, 0 ,'d'},
  16.         {"mmap", 0, 0, 'M'},
  17.         {"nonblock", 0, 0, 'N'},
  18.         {"period-time", 1, 0, 'F'},
  19.         {"avail-min", 1, 0, 'A'},
  20.         {"start-delay", 1, 0, 'R'},
  21.         {"stop-delay", 1, 0, 'T'},
  22.         {"buffer-time", 1, 0, 'B'},
  23.         {"verbose", 0, 0, 'v'},
  24.         {"vumeter", 1, 0, 'V'},
  25.         {"separate-channels", 0, 0, 'I'},
  26.         {"playback", 0, 0, 'P'},
  27.         {"capture", 0, 0, 'C'},
  28.         {0, 0, 0, 0} //结束项
  29. };

  30. 对应代码

  31. while ((c = getopt_long(argc, argv, short_options, long_options, &option_index)) != -1) {
  32.     switch (c) {
  33.         case 'l': //找到了 --list-devices 或者 -l 选项.
  34.             break;
  35.         case 'D': //找到了 --device=hw:0,0 或者 -Dhw:0,0 选项
  36.             printf("device name is [%s].\n", optarg);
  37.             break;
  38.         default: //找到了不可识别的选项.
  39.             printf("unkown opt [%s].", optopt); //位置选项保存在全局 optopt中.
  40.     }
  41. }
阅读(996) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~