向程序传递参数

/*
 * arg.c
 *
 *  Created on: Jul 21, 2013
 *      Author: root
 */
#include <unistd.h>
#include <stdio.h>
int main(int argc, char **argv) {
  int i;
  for(i=0;i<argc;i++)
  {
     if(*argv[i]=='-')
     {
        printf("option:%s\n",argv[i]+1);
     }
     else {
        printf("argument %d:%s\n",i,argv[i]);
    }
  }
  return 0;
}

如果对二级指针 指针数组 二维数组之间的关系不太清楚的话,请查阅C语言程序设计(谭浩强版)第三版 第八章


编译运行:

[root@localhost C_test]# ./arg -i -ldf 'yao' -f yao.c
argument 0:./arg
option:i
option:ldf
argument 3:yao
option:f
argument 5:yao.c

发现-ldf没有像-l -d -f那样处理,这时就要用到getopt函数了。


getopt

函数原型:int getopt(int argc ,char * const * argv,const char * optstring)  

               extern char * optarg

               extern int optind,opterr,optopt

getopt函数将传递给程序的main函数的argc argv作为参数,同时接受一个选项制定符字符串optstring,该字符串告诉getopt哪些选项可用。optstring只是一个字符列表,每个字符代表一个单字符选项。如果一个字符后面紧跟一个冒号,则该选项有一个关联值作为下一个参数。


getopt处理过程:

1   如果选项有一个关联值,则外部变量optarg指向这个值

2   如果选项处理完毕,getopt返回-1,特殊参数--将使getopt停止扫描选项

3   如果遇到一个无法识别的选项,getopt返回一个问号?,并把它保存到外部变量optopt中。

4  如果一个选项要求有一个关联值,但用户并未提供这个值,getopt通常返回一个问号?.如果我们将选项字符串的第一个字符设置为冒号:,那么getopt在用户未提供值的情况下返回冒号:而不是问号?。


外部变量optind为下一个待处理参数的索引,getopt利用它来记录自己的进度。当所有选项参数都处理完毕后,optind将指向argv数组尾部可以找到其余参数的位置,根据POSIX规范的规定,如果opterr是非零值,getopt就会向stderr打印一条错误信息。


/*
 * argopt.c
 *
 *  Created on: Jul 21, 2013
 *      Author: root
 */
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
  int opt;
  while((opt=getopt(argc,argv,":if:lr"))!=-1)
  {
      switch(opt)
      {
      case 'i':
      case 'l':
      case 'r':
         printf("option:%c\n",opt);
         break;
      case 'f':
          printf("filename:%s\n",optarg);
           break;
      case ':':
          printf("option needs a value\n");
          break;
      case '?':
          printf("unknown option:%c\n",optopt);
          break;
      }
  }
   for(;optind<argc;optind++)
   {
       printf("argument:%s\n",argv[optind]);
   }
  return 0;
}


编译运行:

[root@localhost C_test]# ./argopt -i -lr 'yaobing' -f hello.c -e
option:i
option:l
option:r
filename:hello.c
unknown option:e
argument:yaobing


[root@localhost C_test]# ./argopt -l -f
option:l
option needs a value

这样对比下,是不是更清楚了!


getopt_long

是getopt的另一个版本,可以接受双划线(--)开始的长参数


getopt_long在getopt.h头文件中

函数原型:

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


option结构体原型:

  struct option {

  const char *name;

  int has_arg;

  int *flag;

  int val;

  };


   结构中的变量解释:

  const char *name:选项名,前面不带-的

  int has_arg:长选项是否有选项参数,有三种类型(常量),如下

          no_argument(值为0  代表选项没有参数)                          

          required_argument(值为1  代表选项需要参数)      

          optional_argument(值为2   代表选项参数是可选的)    

  int *flag:

  如果该指针为NULL,那么getopt_long返回val字段的值;

  如果该指针不为NULL,那么会使得它所指向的结构填入val字段的值,同时getopt_long返回0

  int val:

  如果flag是NULL,那么val通常是个字符常量,如果短选项和长选项一致,那么该字符就应该与optstring中

  出现的这个选项的参数相同;


  最后一个参数:longindex参数一般赋为NULL即可;如果没有设置为NULL,那么它就指向一个变量,这个变量

  会被赋值为寻找到的长选项在longopts中的索引值,这可以用于错误诊断。

  

   

/*
 * getopt_l.c
 *
 *  Created on: Jul 21, 2013
 *      Author: root
 */
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
int main(int argc, char **argv) {
    int opt;
    char * const short_options=":if:lr";
    struct option long_options[]=
    {
            {"name",1,NULL,'n'},
    };
    while((opt=getopt_long(argc,argv,short_options,long_options,NULL))!=-1)
    {
      switch(opt)
      {
      case 'i':
      case 'l':
      case 'r':
          printf("option is %c\n",opt);
          break;
      case 'f':
          printf("filename is %s\n",optarg);
          break;
      case 'n':
          printf("name:%s\n",optarg);
          break;
      case ':':
          printf("option needs a value!");
          break;
      case '?':
          printf("unknown option:%c",optopt);
          break;
      }
    }
    for(;optind<argc;optind++)
    {
        printf("arguments:%s",argv[optind]);
    }
 return 0;
}

和上面代码比较,就多了struct option而已。


运行  

[root@localhost C_test]# ./getopt_long -rl -f he.c --name yao
option is r
option is l
filename is he.c
name:yao


现在长选项 短选项后跟的参数都可以读取到了 ,可以休息下了!




参考链接:http://blog.163.com/shaohj_1999@126/blog/static/63406851201031425650111/


             

  

你可能感兴趣的:(getopt,getopt_long)