侧边栏壁纸
博主头像
noerror

虚灵不寐,众理具而万事出。

  • 累计撰写 239 篇文章
  • 累计创建 9 个标签
  • 累计收到 2 条评论
标签搜索

目 录CONTENT

文章目录

getopt函数用法详解

noerror
2022-11-09 / 0 评论 / 0 点赞 / 235 阅读 / 2,446 字 / 正在检测是否收录...

getopt函数用法详解

getopt函数简介

  • 头文件包含
#include <unistd.h>
#include <getopt.h>
  • 函数定义
int getopt(int  argc , char * const  argv[] ,
           const char * optstring );
extern char * optarg ;
extern int  optind ,  opterr ,  optopt ;
int getopt_long(int  argc , char * const  argv[] ,
           const char * optstring ,
           const struct option * longopts , int * longindex );
int getopt_long_only(int  argc , char * const  argv[] ,
           const char * optstring ,
           const struct option * longopts , int * longindex );

getopt函数常见使用错误

  • 编译错误
    warning: implicit declaration of function ‘getopt’ [-Wimplicit-function-declaration]
    解决办法:包含头文件
#include <unistd.h>
#include <getopt.h>

getopt函数详细描述

getopt ()函数解析命令行参数。它的参数argc和argv是在程序调用时传递给main ()函数的参数计数和数组。以\(aq-\(aq)开头的argv元素(并不完全是“-”或“--”)是一个option元素。这个元素的字符(除了初始的\(aq-\(aq)之外)是option字符。如果重复调用getopt (),它会从每个option元素中连续返回每个option字符。
变量optind是argv 中要处理的下一个元素的索引,系统将该值初始化为1。调用者可以将其重置为1,以重新扫描同一个argv 或扫描新的参数向量。
如果getopt ()找到另一个选项字符,它将返回该字符,更新外部变量optind和静态变量nextchar,以便对getopt ()的下一次调用可以使用以下选项字符或argv-element继续扫描。
如果没有更多的选项字符,getopt ()返回-1。那么optind是argv中第一个不是选项的PPPP2元素的索引。
optstring是包含合法选项字符的字符串。如果这样的字符后面跟一个冒号,则该选项需要一个参数,因此getopt ()在同一个argv-element中放置一个指向以下文本的指针,或者在optarg 中放置一个指向以下PPPP8-element的文本的指针,两个冒号表示一个选项接受一个可选参数;如果当前PPPP8-element中有文本(即,与选项名称本身在同一个单词中,例如“-oarg”),则在optarg中返回该文本,否则PPPP11被设置为零。这是一个GNU扩展。如果optstring包含后跟分号的 W ,则 -W foo 被视为长选项--foo (POSIX.2为实现扩展保留了 -W 选项)这种行为是GNU扩展,在glibc 2之前的库中不可用。
默认情况下,getopt ()在扫描时会对argv的内容进行置换,因此最终所有非选项都在末尾。还实现了另外两种扫描模式。如果optstring的第一个字符是\(aq+\(aq)或者设置了环境变量 POSIXLY_CORRECT ,那么一旦遇到非option参数,option处理就会停止。如果PPPP3的第一个字符是\(aq-\(aq),那么每个非option pargv元素都被当作字符代码为1的option的参数来处理(这是由那些希望options和其他PPPP2元素以任何顺序排列并关心两者顺序的程序使用的)。特殊参数“--”强制结束option-scanning,而不管扫描模式如何。
在处理选项列表时,getopt ()可以检测两种错误:(1)在optstring中没有指定的选项字符和(2)缺少选项参数(即,命令行末尾的选项没有预期的参数)。此类错误的处理和报告如下:

  • 默认情况下,getopt ()在标准错误上打印一条错误消息,将错误的选项字符放入optopt 中,并返回\(aq?\(aq作为函数结果。
  • 如果调用方已将全局变量opterr设置为零,则getopt ()不会打印错误消息。调用者可以通过测试函数返回值是否为\(aq?\(aq.(默认情况下,opterr具有非零值)来确定存在错误
  • 如果optstring的任何可选\(aq+\(aq或\(aq-\(aq)后面的第一个字符是冒号(\(aq:\(aq),那么getopt ()同样不会打印错误消息。此外,它返回\(aq:\(aq)而不是\(aq?\(aq)以指示缺少的选项参数。这允许调用者区分两种不同类型的错误。getopt_long() and getopt_long_only() getopt_long ()函数的工作方式类似于getopt (),只是它也接受以两个破折号开头的长选项。(如果程序只接受长选项,则optstring应指定为空字符串(“”),而不是NULL。)如果缩写是唯一的或者与某个定义的选项完全匹配,则长选项名称可以缩写。long选项可以采用 --arg=param 或"--arg param" 形式的参数

longopts是指向中声明为的struct option数组的第一个元素的指针

struct option {
   const char *name;
   int         has_arg;
   int        *flag;
   int         val;
};

不同字段的含义是:

  • name是long选项的名称。
  • has_arg是:no_argument(或0),如果选项不带参数;如果选项需要参数,则为required_argument(或1);如果选项采用可选参数,则为optional_argument(或2)。
  • flag指定如何为长选项返回结果。如果flag为空,则getopt_long ()返回val。(例如,调用程序可以将PPPP4设置为等效的短选项字符。)否则,getopt_long ()返回0,PPPP3指向一个变量,如果找到选项,该变量设置为PPPP4,但如果没有找到选项,则保持不变。
  • val是要返回或加载到flag所指向的变量中的值。

数组的最后一个元素必须用零填充。
如果longindex不为NULL,则它指向一个变量,该变量被设置为long选项相对于longopts 的索引
getopt_long_only ()类似于getopt_long (),但是\(aq-\(aq)和“--”可以表示长选项。如果以\(aq-\(aq(不是“--”)开头的选项不匹配长选项,但匹配短选项,则它被解析为短选项。

getopt函数返回值

如果成功找到一个选项,那么getopt ()返回选项字符。如果已经解析了所有命令行选项,则getopt ()返回-1。如果getopt ()遇到optstring 中没有的选项字符,则返回\(aq?\(aq)。如果getopt ()遇到缺少参数的选项,则返回值取决于optstring :中的第一个字符,如果它是\(aq:\(aq,则返回\(aq:\(aq);否则返回\(aq?\(aq)。
当识别出短选项时,PPP0和getopt_long_only ()也返回选项字符。对于long选项,如果flag为空,则返回val,否则返回0。Error和-1的返回与getopt ()加\(aq?\(aq)对于不明确的匹配或无关参数的返回相同。

getopt函数其他说明

一个程序扫描多个参数向量,或多次重新扫描同一向量,并希望在optstring 开始时使用GNU扩展,如\(aq+\(aq和\(aq-\(aq),或在两次扫描之间更改 POSIXLY_CORRECT 的值,必须通过将optind重置为0而不是传统的值1来重新初始化getopt ()。(重置为0会强制调用内部初始化例程,该例程会重新检查 POSIXLY_CORRECT 并检查optstring )中的GNU扩展

getopt函数使用举例

getopt()下面这个简单的示例程序使用getopt ()来处理两个程序选项:没有关联值的-n ;和需要关联值的"-t val" 。

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

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

   nsecs = 0;
   tfnd = 0;
   flags = 0;
   while ((opt = getopt(argc, argv, "nt:")) != \-1) {
       switch (opt) {
       case \(aqn\(aq:
           flags = 1;
           break;
       case \(aqt\(aq:
           nsecs = atoi(optarg);
           tfnd = 1;
           break;
       default: /* \(aq?\(aq */
           fprintf(stderr, "Usage: %s [\-t nsecs] [\-n] name\en",
                   argv[0]);
           exit(EXIT_FAILURE);
       }
   }

   printf("flags=%d; tfnd=%d; nsecs=%d; optind=%d\en",
           flags, tfnd, nsecs, optind);

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

   printf("name argument = %s\en", argv[optind]);

   /* Other code omitted */

   exit(EXIT_SUCCESS);
}

getopt_long()下面的示例程序演示了getopt_long ()及其大部分功能的使用。

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

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

   while (1) {
       int this_option_optind = optind ? optind : 1;
       int option_index = 0;
       static struct option long_options[] = {
           {"add",     required_argument, 0,  0 },
           {"append",  no_argument,       0,  0 },
           {"delete",  required_argument, 0,  0 },
           {"verbose", no_argument,       0,  0 },
           {"create",  required_argument, 0, \(aqc\(aq},
           {"file",    required_argument, 0,  0 },
           {0,         0,                 0,  0 }
       };

       c = getopt_long(argc, argv, "abc:d:012",
                long_options, &option_index);
       if (c == \-1)
           break;

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

       case \(aq0\(aq:
       case \(aq1\(aq:
       case \(aq2\(aq:
           if (digit_optind != 0 && digit_optind != this_option_optind)
             printf("digits occur in two different argv\-elements.\en");
           digit_optind = this_option_optind;
           printf("option %c\en", c);
           break;

       case \(aqa\(aq:
           printf("option a\en");
           break;

       case \(aqb\(aq:
           printf("option b\en");
           break;

       case \(aqc\(aq:
           printf("option c with value \(aq%s\(aq\en", optarg);
           break;

       case \(aqd\(aq:
           printf("option d with value \(aq%s\(aq\en", optarg);
           break;

       case \(aq?\(aq:
           break;

       default:
           printf("?? getopt returned character code 0%o ??\en", c);
       }
   }

   if (optind < argc) {
       printf("non\-option ARGV\-elements: ");
       while (optind < argc)
           printf("%s ", argv[optind++]);
       printf("\en");
   }

   exit(EXIT_SUCCESS);
}
0

评论区