• C语言处理参数的 getopt() 函数


    前言

    C语言程序主要通过 main 函数的参数来传递命令行参数:

    1. // 默认传递命令行参数
    2. int main(int argc ,char * argv[])
    3. {
    4. ...
    5. }

    其中 argc 表示参数个数(包含程序本身),argv是保存所有这些参数的二级数组。

    我们可以直接操作这两个变量来处理参数,但是C标准库提供了一个更丰富的处理参数的方法,就是 getopt()。

    getopt 介绍

    函数声明如下:

    1. #include
    2. int getopt(int argc, char * const argv[], const char *optstring);

    getopt() 函数用于解析命令行参数。它的 argc 和 argv 参数通常直接从 main() 的参数直接传递而来。

    optstring 是可以处理选项字母组成的字符串。该字串里的每个字符对应于一个以 ‘-’ 开头的选项。如果该字串里的任一字符后面有冒号,那么这个选项就要求有参数(如“hd:”对应于 '-h' 和 '-d', 其中 '-d' 后需接参数)。而如果选项后面接两个冒号,则说明这个选项后的参数是可选的,即可带参数也可不带参数。

    全局变量

    当给定 getopt() 命令参数的数量 (argc)、指向这些参数的数组 (argv) 和选项字串 (optstring) 后,getopt() 将返回第一个选项,并设置一些全局变量。

    1. extern char *optarg;
    2. extern int optind, opterr, optopt;
    • char *optarg : 指向当前选项的参数字串(如果有)
    • int optind : 变量 optind 是 argv 中要处理的下一个元素的索引。系统将此值初始化为 1。该值随着 getopt() 的调用而变化,调用者可以将其重置为 1 以重新开始扫描相同的 argv,或者扫描新的参数向量。
    • int opterr : 错误信息打印标志,这个变量非零时,getopt() 函数会为"无效选项"和"缺少参数选项"两种情况输出其错误信息.
    • int optopt : 当发现无效选项字符之时,optopt包含了所发现的无效选项字符

    处理机制

    getopt() 调用时会根据 optind 和 optstring 遍历选项和参数,如果找到一个选项字符,则返回该字符,同时更新全局变量 optind,optarg 以及静态变量 nextchar,以便下一次调用 getopt() 时可以继续扫描。

    如果 getopt() 被重复调用,它会依次返回每个选项字符。如果所有可识别的选项都被扫描过,将返回 -1,此时 optind 是第一个不是选项的 argv 元素的索引。

    扫描模式

    默认情况下,getopt() 会在扫描时置换 argv 的内容,以便扫描完成后所有的非选项都处于末尾。但还提供了另外两种扫描模式。

    1. 一旦遇到非选项参数就立即停止,通过 optstring 的一个字符设置为 '+' 来选择这种模式;

    2. 每个非选项 argv 元素都被处理为好像它是具有字符代码 1 的选项的参数一样,此时碰到那些没有选项对应的参数时不会报错也不会退出,而是认为它是选项“1”的参数。通过 optstring 的第一个字符设置为 ‘-’ 来选择这种模式。

    注:无论处于那种扫描模式,碰到参数 '--' 都会强制结束选项扫描。

    getopt出错处理机制

    在处理选项列表时,getopt() 可以检测到两种错误:

    1. 未在 optstring 中定义的选项字符;

    2. 缺少选项参数;

    默认情况下, getopt() 会打印一条错误消息,将错误的选项字符放在 optopt 中,并返回 '?' 作为函数结果。但如果我们想要其他的处理方式,可以有以下做法:

    1. 在调用 getopt() 前设置 opterr 为零,此时 getopt() 不会输出错误信息,我们可以通过返回值是否为 '?' 来进行不同的处理。

    2. 将 optstring 的第一个字符设置为 ‘+’ 或者 '-',此时 getopt() 同样不会输出错误信息,同时可以根据返回值是 ‘?’ 还是 ':' 来做不同的处理。 ‘?’ 表示未定义选项,':' 表示缺少选项参数

    示例

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

    1. #include
    2. #include
    3. #include
    4. int main(int argc, char *argv[])
    5. {
    6. int flags, opt;
    7. int nsecs, tfnd;
    8. nsecs = 0;
    9. tfnd = 0;
    10. flags = 0;
    11. while ((opt = getopt(argc, argv, "nt:")) != -1) {
    12. switch (opt) {
    13. case 'n':
    14. flags = 1;
    15. break;
    16. case 't':
    17. nsecs = atoi(optarg);
    18. tfnd = 1;
    19. break;
    20. default: /* '?' */
    21. fprintf(stderr, "Usage: %s [-t nsecs] [-n] name\n",
    22. argv[0]);
    23. exit(EXIT_FAILURE);
    24. }
    25. }
    26. printf("flags=%d; tfnd=%d; nsecs=%d; optind=%d\n",
    27. flags, tfnd, nsecs, optind);
    28. if (optind >= argc) {
    29. fprintf(stderr, "Expected argument after options\n");
    30. exit(EXIT_FAILURE);
    31. }
    32. printf("name argument = %s\n", argv[optind]);
    33. exit(EXIT_SUCCESS);
    34. }

    参考链接

    getopt函数_sdoyuxuan的博客-CSDN博客_getopt函数

    man entry of getopt

  • 相关阅读:
    「Python实用秘技08」一行代码解析地址信息
    java版 设计一个程序, 输入a,b,c三个整数, 输出最大的数.
    LangChain结合milvus向量数据库以及GPT3.5结合做知识库问答之一 --->milvus的docker compose安装
    什么是计算机网络
    LayaBox---TypeScript---高级类型
    最优秀的完整的数字音频工作站水果音乐FL Studio21.1.1.3750中文解锁版
    操作系统之调度算法
    【数据结构】单链表定义的介绍及增删查改的实现
    如何开发npm依赖包,并发布到npm
    双十一购物狂欢节准备好买什么了吗?双十一这些好物不能错过
  • 原文地址:https://blog.csdn.net/rangfei/article/details/126845978