C语言getopt函数使用方法

本文详细介绍了C语言中getopt函数在处理命令行选项和参数时的六个案例,包括选项要求参数、允许无参数选项、选项顺序、额外参数处理以及错误处理等。
摘要由CSDN通过智能技术生成

一、案例1

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

// 这几个是头文件带的变量
// extern char *optarg;
// extern int optind, opterr, optopt;

// -a
// 选项后面一定要有参数,参数和选项之间可以有空格,也可以没空格。解析出的参数放在
// optarg 变量里。 examples:
// ./a.out -a 6
// ./a.out -a6
// ./a.out -a s
// 参数也可以用引号包裹起来,这样可以包含空格.
// ./a.out -a "s b"
// ./a.out -a"s b"
void opt_example1(int argc, char **argv) {
  const char *optstr = "a:";
  char ch;
  while ((ch = getopt(argc, argv, optstr)) != -1) {
    switch (ch) {
    case 'a':
      printf("have option: -a\n");
      printf("the argument of -a is %s\n", optarg);
      break;
    }
  }
}

二、案例2

// 选项后面可以有参数,也可以没有参数。但是有参数情况下,必须没有空格。若有空格,得到的参数是
// null examples:
// ./a.out -b
// ./a.out -b hello
void opt_example2(int argc, char **argv) {
  const char *optstr = "b::";
  char ch;
  while ((ch = getopt(argc, argv, optstr)) != -1) {
    switch (ch) {
    case 'b':
      printf("have option: -b\n");
      printf("the argument of -b is %s\n", optarg);
      break;
    }
  }
}

三、案例3

// -c 选项后面不能有参数。如果有参数,会被当成别的选项. 打印 optarg 得到 null
// examples:
// ./a.out -c
void opt_example3(int argc, char **argv) {
  const char *optstr = "c";
  char ch;
  while ((ch = getopt(argc, argv, optstr)) != -1) {
    switch (ch) {
    case 'c':
      printf("have option: -c\n");
      printf("the argument of -c is %s\n", optarg);
      break;
    }
  }
}

四、案例4

// -c 选项和 -d 选项可以合并
// examples:
// ./a.out -c -d
// ./a.out -d -c
// ./a.out -cd
// ./a.out -dc
void opt_example4(int argc, char **argv) {
  const char *optstr = "cd";
  char ch;
  while ((ch = getopt(argc, argv, optstr)) != -1) {
    switch (ch) {
    case 'c':
      printf("have option: -c\n");
      printf("the argument of -c is %s\n", optarg);
      break;
    case 'd':
      printf("have option: -d\n");
      printf("the argument of -d is %s\n", optarg);
      break;
    }
  }
}

五、案例5

// argv 中不以 "-" 开头的、并且不是跟在选项后面的,不会被 getopt() 解析
// 不被解析意味着, 调用 getopt() 之后会改变 argv 的元素顺序, 被解析的 选项+参数 们 在前,没被解析的在后
// examples:
// ./a.out shenme -a hello -b world
//     新版 argv 会是 ./a.out -a hello -b world shenme
// ./a.out -a hello shenme -b world
//     新版 argv 会是 ./a.out -a hello -b world shenme
// 被解析的选项们的顺序是不会被改变的. 如果没空格,也不会被更细出空格
// ./a.out shenme -b world -a hello
//     新版 argv 会是 ./a.out -b world -a hello shenme
// ./a.out shenme -bworld -a hello
//     新版 argv 会是 ./a.out -bworld -a hello shenme
// 调用 getopt() 后, optind 会指向第一个非选项和参数的位置
void opt_example5(int argc, char** argv)
{
    printf("original argv is:");
    for (int i = 0; i < argc; i++)
    {
        printf(" %s", argv[i]);
    }
    printf("\n");
 
    char ch;
    const char* optstr = "a:b:c:";
    while( (ch = getopt(argc, argv, optstr)) != -1 )
    {
        switch(ch)
        {
        case 'a':
            break;
        case 'b':
            break;
        }
    }
 
    printf("after getopt, argv is:");
    for (int i = 0; i < argc; i++)
    {
        printf(" %s", argv[i]);
    }
    printf("\n");
 
    printf("and now, optind = %d, argv[%d] = %s\n",
        optind, optind, argv[optind]);
}

六、案例6

// 利用 optind 判断是否输出了指定选项和参数外的参数
// 若只输入了符合 optstr 的 argv, 则 optind 小于 argc
// 若输入了额外的参数, 则 optind 等于 argc
// examples:
// ./a.out -a hello world
//    输出:
// optind = 3, argv[3] = world
// you have entered extra arguments: world
//
// ./a.out -a 0 hello world
//    输出:
// optind = 3, argv[3] = hello
// you have entered extra arguments: hello world
void opt_example6(int argc, char **argv) {
  char ch;
  const char *optstr = "a:b:c:";
  while ((ch = getopt(argc, argv, optstr)) != -1) {
    switch (ch) {
    case 'a':
      break;
    case 'b':
      break;
    }
  }

  printf("optind = %d, argv[%d] = %s\n", optind, optind, argv[optind]);

  if (optind < argc) {
    printf("you have entered extra arguments:");
    for (int i = optind; i < argc; i++) {
      printf(" %s", argv[i]);
    }
    printf("\n");
  }
}

七、案例7

// argv 可能包含 getopt() 无法解析的选项,也就是不在 optstr 中的选项
// 这样的选项,对应到 getopt() 返回 `?` , 可以设置为打印help信息
// examples:
// ./a.out -s
//   输出
// ./a.out: invalid option -- 's'
// Usage: ./a.out -a <a_arg> -b <b_arg>
void opt_example7(int argc, char **argv) {
  char ch;
  const char *optstr = "a:b:c:";
  while ((ch = getopt(argc, argv, optstr)) != -1) {
    switch (ch) {
    case 'a':
      break;
    case 'b':
      break;
    case '?':
      printf("Usage: %s -a <a_arg> -b <b_arg>\n", argv[0]);
    }
  }
}

八、案例8

void help_and_die(char *argv0) {
  printf("Usage: %s [-hv] -s <num> -E <num> -b <num> -t <file>\n", argv0);
  printf("Options:\n");
  printf("  -h         Print this help message.\n");
  printf("  -v         Optional verbose flag.\n");
  printf("  -s <num>   Number of set index bits.\n");
  printf("  -E <num>   Number of lines per set.\n");
  printf("  -b <num>   Number of block offset bits.\n");
  printf("  -t <file>  Trace file.\n");
  printf("\n");
  printf("Examples:\n");
  printf("  linux>  %s -s 4 -E 1 -b 4 -t traces/yi.trace\n", argv0);
  printf("  linux>  %s -v -s 8 -E 2 -b 4 -t traces/yi.trace\n", argv0);
  exit(0);
}
// CSAPP CacheLab 的例子,模拟 csim-ref 的参数解析
void opt_example8(int argc, char *argv[]) {
  const char *optstr = "hvs:E:b:t:";
  char ch;

  bool verbose = false;
  int s = -1;
  int E = -1;
  int b = -1;
  int t = -1;
  while ((ch = getopt(argc, argv, optstr)) != -1) {
    switch (ch) {
    case 'h':
      help_and_die(argv[0]);
      exit(0);
      break;
    case 'v':
      verbose = true;
      break;
    case 's':
      s = atoi(optarg);
      break;
    case 'E':
      E = atoi(optarg);
      break;
    case 'b':
      b = atoi(optarg);
      break;
    case 't':
      t = atoi(optarg);
      break;
    case '?':
      help_and_die(argv[0]);
      break;
    }
  }

  if (optind == 1) {
    printf("%s: Missing required command line argument\n", argv[0]);
    help_and_die(argv[0]);
  }
}
  • 10
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
内容: 1、Linux系统C语言编程连接MySql数据库实现的用户 用户组 用户策略 管理系统(getopt解析命令行参数).c 代码的源文件。 user-usergroup-authoritys.vsd user-usergroup-authoritys.jpg 数据库的图,以及图片。 2、部分操作: 显示操作 -S //-S显示名为xxx用户具体信息(所在组、改组定义了什么策略) 提示必须加-n参数 ./userGroupUser users -S //显示用户表 用户组表 所有信息 ./userGroupUser users -S -n root //显示用户表内 name=root的用户的信息 //可以显示该用户对应用户组内 所在的组 定义的策略信息 新增操作 -A /* 全:./userGroupUser users -A s -n test3 -p test3 -a 2 -groot -rasdc*/ /**添加用户 (-g(+) group ; -r(+) remark)**/ //新增用户的时候必须有-n|-p|-a选项 name password authentication //一次性输入所有选项也是错误的 需要为每个参数赋值 // printf("ADD -- Please enter necessary parameters -n|-p|-a,and assign a value to each parameter!\n"); //-g的参数必须紧跟 否则改用户会默认加入root组; //-r的参数必须紧跟 否则判定为输入为空 //当-g选项没有加参数时候 默认该用户属于root组; //-g后的参数不存在则加入失败,提示该用户组不存在 ./userGroupUser users -A -n ddf -p aa -a 1//添加用户 name=ddf authentication=1 默认加到用户组root //insert into users values(7,'ddf','aa','2018-7-2 16:23:39',1,1,' ','KEY认证需要的文件',''); ./userGroupUser users -A -n dds -a 1 -p sd -rkj -gaa //添加用户 name=dds authentication=1 group=aa //insert into users values(6,'dds','sd','2018-7-2 16:20:33',1,1,' ','KEY认证需要的文件','kj'); //-g后的参数 用户组名不存在不允许加入users usergroups表 /**添加用户组 (-e(+) enable; -o(+) policy; -r(+) remark)**/ /*全: ./userGroupUser usergroups -A -n dd -e1 -oWEB,HTTP -rddWH*/ //新增用户时候有必须参数-n选项 name //只有-n参数时候 策略状态( enable_type_)为0 默认策略( policy_type_)为所有策略资源 //其他参数 -e(+) 策略状态enable; -o(+)策略类型policy; -r(+) 标记内容remark ./userGroupUser usergroups -A //提示 Please enter other parameters when you want to add someone!! ./userGroupUser usergroups -A -n aa //用户组表中添加name=aa policy默认如下 remark默认为空 的用户组信息 //insert into usergroups values(2,'aa','2018-7-2 16:14:19',0,'GET,HEAD,POST,PUT,DELETE,OPTIONS','') ./userGroupUser usergroups -A -n aa -oGET -rasd //向用户组中添加 name=aa policy=GET remark=asd的用户 //insert into usergroups values(2,'aa','2018-7-2 16:14:46',0,'GET','asd'); 修改操作 /**修改用户**/ /*全:./userGroupUser users -E -n test33 -p test33 -a 1 -gaa -rtest3totest33 where name test3 password test3*/ //修改用户操作必须有where name password 字符;且where后个数需为偶数; name password参数需参数值 //判断要进行改的用户是不是管理员用户,禁止对管理员用户进行任何操作 //参数 :-n newname;-p newpassword;-a authentication; -ggroup; -rremark; ./userGroupUser users -E -n test22 where name test2 password test2 //把名为test2密码为test2的用户名改为test22 /**修改用户组**/ /*全:./userGroupUser usergroups -E -n aaa -e1 -oGET,HEAD -raatoaaa where name aa*/ //修改用户组操作必须有where name字符;且where后个数需为偶数; name 参数需参数值 //判断要进行改的用户是不是管理员用户,禁止对管理员用户进行任何操作 //参数 : -n newname;-eenabled ; -opolicy; -rremark; ./userGroupUser usergroups -E -n AA where name aa//把aa用户名改为AA ./userGroupUser usergroups -E -n csa -e1 -oAAA,WEB,HTTP -rAAA where name aaa //修改 用户组name为aaa为 name=csa enable=1 policy=AAA,WEB,HTTP remark=AAA 删除操作 ./userGroupUser users -D // 提示 Please enter other parameters when you want to add someone!! ./userGroupUser users -D -n root -p r //root用户不允许删除 //name或passwd 不正确不允许删除 ./userGroupUser usergroups -D //提示 Please enter other parameters when you want to add someone!! ./userGroupUser usergroups -D -n as//判断是否有用户属于该用户组 若有用户属于该用户组 不允许删除该用户组 //root 用户组不允许删除

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值