linux常用函数详解

发布: 2007-06-05 16:38

一。命令行参数的分析

    几乎所有的GNU/Linux程序都遵循一些同样的命令行解释习惯,程序的参数通常分为了两大类:选项(option)或者一些标志(flag)、其他参数。选项(option)主要是提供给程序一些运行上的选择,而其他参数则通常是提供给程序运行的输入之类的值。按照习惯,选项通常有两种表达形式:

  - 短形式:通常是由一个“-”加上一个字母组合而成。这种形式的好处是输入快捷。

  -- 长形式:通常是由两个“-”加上一个单词组合而成。这种形式的好处是形象、好记、直观。

  经常使用的解析函数是getopt和getopt_long.
  但是函数getopt只能解析短形式的参数,而getopt_long则既可以解析短形式的参数,也可以解析长形式的参数。因此如果想让你的程序能同时支持两种类型的参数,则需要使用后者。

  函数声明在#include <getopt.h>文件中,但有的unix操作系统并不带这个参数,需要自己实现。
  上面两个函数的声明为:
  int getopt(int argc,char const **argv, const char *optstring);
  /**
  * @param optstring 所有可能的短参数名组成的字符串
  * @param longindex 将会填充查找到的参数在字符串中的位置
  */
  int getopt_long(int argc,char const **argc,
        const char *optstring,const struct option *longopts,
        int *longindex);

  extern char *optarg;
  extern int optind,opterr,optopt;

  struct option {
    char *name;        //参数的长名字
    int has_flag;      //是否需要,0,不需要,1,必须,2,可选
    int *flag;          //如没有特殊需要,设置为NULL即可
    int value;          //短名字,一般是一个字符
  };

  getopt_long是getopt的扩展.getopt接受的命令行参数只可以是以(-)开头,而getopt_long还可以接受(--)开头的参数.一般以(-)开头的参数的标志只有一个字母,而以(--)开头的参数可以是一个字符串.
  参数说明:
    argc,和argv参数是main函数的参数.optstring指出了我们可以接受的参数.其一般的形式为:参数1[:]参数2[:].... 其中参数是我们可以接受的参数,如果后面的冒号没有省略,那么表示这个参数出现时后面必需要带参数值. 比如一个optstring为abc:d:表示这个参数选项可以为a,b,c,d其中c,d出现时候必须要有参数值.如果我们输入了一个我们没有提供的参数选项.系统将会说 不认识的 选项. getopt返回我们指定的参数选项.同时将参数值保存在optarg中,如果已经分析完成所有的参数函数返回-1.这个时候optind指出非可选参数的开始位置.

  #include <stdio.h>
#include <unistd.h>

int main(int argc,char **argv)
{
int is_a,is_b,is_c,is_d,i;
char *a_value,*b_value,*c_value,temp;

is_a=is_b=is_c=is_d=0;
  a_value=b_value=c_value=NULL;
 
if(argc==1)
  {
      fprintf(stderr,"Usage:%s [-a value] [-b value] [-c value] [-d] arglist ...n",argv[0]);
      exit(1);
  }

while((temp=getopt(argc,argv,"a:b:c:d"))!=-1)
  {
    switch (temp) 
    {
        case 'a':
          is_a=1;
          a_value=optarg;
        break;
        case 'b':
            is_b=1;
            b_value=optarg;
          break;
        case 'c':
            is_c=1;
            c_value=optarg;
          break;
        case 'd':
            is_d=1;
            break;
    }
  }

printf("Option has a:%s with value:%sn",is_a?"YES":"NO",a_value);
printf("Option has b:%s with value:%sn",is_b?"YES":"NO",b_value);
printf("Option has c:%s with value:%sn",is_c?"YES":"NO",c_value);
printf("OPtion has d:%sn",is_d?"YES":"NO");
i=optind;
while(argv[i]) printf(" with arg:%sn",argv[i++]);

exit(0);


  getopt_long比getopt复杂一点,不过用途要比getopt广泛.
  struct option 指出我们可以接受的附加参数选项. 
  name:指出长选项的名称(如我们的option1) 
  has_flag:为0时表示没有参数值,当为1的时候表明这个参数选项要接受一个参数值.为2时表示参数值可以有也可以没有. 
optarg:指出函数的返回值.如果为NULL,那么返回val,否则返回0.并将longindex赋值为选项所在数组(longopts)的位置.

  /* 这个实例是从 GNU Libc 手册上看到的 */

#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>


int main (int argc, char **argv)
{
  int c;

  while (1)
    {
      struct option long_options[] =
        {
          {"add", 1, 0, 0},
          {"append", 0, 0, 0},
          {"delete", 1, 0, 0},
          /* 返回字符c,等同于 -c 选项 */
          {"create", 0, 0, 'c'},
          {"file", 1, 0, 0},
          /* 数组结束 */
          {0, 0, 0, 0}
        };
      /* getopt_long stores the option index here. */
      int option_index = 0;

      c = getopt_long (argc, argv, "abc:d:",
                      long_options, &option_index);

      /* Detect the end of the options. */
      if (c == -1)
        break;

      switch (c)
        {
        case 0:
          printf ("option %s", long_options[option_index].name);
          if (optarg)
            printf (" with arg %sn", optarg);
          break;

        case 'a':
          puts ("option -an");
          break;

        case 'b':
          puts ("option -bn");
          break;

        /* 可能是-c --creat参数指出来的 */
        case 'c':
          printf ("option -c with value `%s'n", optarg);
          break;

        case 'd':
          printf ("option -d with value `%s'n", optarg);
          break;
        }
    }

  exit (0);
}

  当我们输入了错误的选项后,系统会给出错误的提示,如果我们想屏蔽这个信息,我们可以设置opterr为0,对于错误的选项,函数分析时候返回一个'?'字符.我们可以自己对这个字符进行处理.


原文: http://qtchina.tk/?q=node/50

Powered by zexport