如何构建符合 POSIX 实用程序约定的Shell-CLI —— Argtable3 源码解析(2)

最后

一次偶然,从朋友那里得到一份“java高分面试指南”,里面涵盖了25个分类的面试题以及详细的解析:JavaOOP、Java集合/泛型、Java中的IO与NIO、Java反射、Java序列化、Java注解、多线程&并发、JVM、Mysql、Redis、Memcached、MongoDB、Spring、Spring Boot、Spring Cloud、RabbitMQ、Dubbo 、MyBatis 、ZooKeeper 、数据结构、算法、Elasticsearch 、Kafka 、微服务、Linux。

这不,马上就要到招聘季了,很多朋友又开始准备“金三银四”的春招啦,那我想这份“java高分面试指南”应该起到不小的作用,所以今天想给大家分享一下。

image

请注意:关于这份“java高分面试指南”,每一个方向专题(25个)的题目这里几乎都会列举,在不看答案的情况下,大家可以自行测试一下水平 且由于篇幅原因,这边无法展示所有完整的答案解析

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

  • 显示选项语法及帮助

  • 打扫干净

  • 完整的使用Argtable3的流程图

  • 相关链接

如何构建符合 POSIX 实用程序约定的Shell-CLI

=============================================================================================

What is Argtable


Argtable是一款开源的ANSI C library,用来解析GNU样式的命令行选项。它通过定义可用于指定命令行语法的声明式API,从而简化了命令行的分析。

argtable将自动生成一致的错误处理逻辑和命令行语法的文本描述,这对于一个健壮的cli程序来说,是非常必要的,但是很繁琐。

Introduction of Argtable3


解析程序的命令行一直以来都是一个分散注意力的主要编程任务。Argtable3 库通过允许程序员将源代码中的命令行选项直接定义为静态的结构数组来简化作业, 然后**

将该数组传递给argtable3库函数,这些函数就会相应地解析命令行。从命令行中提取的值直接保存到用户定义的程序变量中**,主程序就可以访问这些变量。

argtable3还可以从同一数组中生成命令行语法的描述,以便显示为联机帮助。根据第三条BSD许可条款,此库是免费的。 注意:argtable3不向后兼容

Quick Start


demo code

  • 入门小例子

// 引入 argtable3

#include “argtable3.h”

/* global arg_xxx structs */

struct arg_lit *help;

struct arg_end *end;

int main(int argc, char *argv[]) {

/* the global arg_xxx structs are initialised within the argtable */

void *argtable[] = {

help = arg_litn(NULL, “help”, 0, 1, “display this help and exit”),

end = arg_end(20)

};

int exitcode = 0;

char program[] = “argtable”;

arg_parse(argc, argv, argtable);

/* special case: ‘–help’ takes precedence over error reporting */

if (help->count > 0) {

printf(“Usage: %s”, program);

arg_print_syntax(stdout, argtable, “\n”);

printf(“Demonstrate command-line parsing in argtable3.\n\n”);

arg_print_glossary(stdout, argtable, " %-25s %s\n");

exitcode = 0;

/* deallocate each non-null entry in argtable[] */

arg_freetable(argtable, sizeof(argtable) / sizeof(argtable[0]));

}

return exitcode;

}

  • 运行

./argtable --help

输出

Usage: argtable [–help]

Demonstrate command-line parsing in argtable3.

–help display this help and exit

how it works

Argtable3 提供了一组arg_xxx结构,一个用于它支持的每种类型的参数(文字、整数、双精度、字符串、文件名等),

并且每个结构都能够在命令行上处理该参数的多次出现。此外,可以为每个选项提供可互换使用的替代短选项 (-x)或长选项 (–xx) 形式

事实上,每个选项甚至可以选择多个替代的短选项或长选项,或两者兼而有之。

要定义命令行选项,您必须为arg_xxx所需的每种类型的参数(文字、整数、双精度、字符串、文件名等)创建一个结构体,并将它们整理到我们称为参数表(argument table)的数组中。

参数表中结构的顺序定义了命令行选项的预期顺序,不过解析顺序实际上只对未标记的选项重要(和python的函数传参规则类似)。

参数表本身只是一个void指针数组void* arg_table[]),

按照惯例,每个arg_xxx结构都有一个已知的arg_hdr结构体作为其第一个条目,Argtable3 函数使用它来标识结构体。

arg_hdr

typedef struct arg_hdr {

char flag; /* Modifier flags: ARG_TERMINATOR, ARG_HASVALUE. */

const char* shortopts; /* String defining the short options */

const char* longopts; /* String defiing the long options */

const char* datatype; /* Description of the argument data type */

const char* glossary; /* Description of the option as shown by arg_print_glossary function */

int mincount; /* Minimum number of occurences of this option accepted */

int maxcount; /* Maximum number of occurences if this option accepted */

void* parent; /* Pointer to parent arg_xxx struct */

arg_resetfn* resetfn; /* Pointer to parent arg_xxx reset function */

arg_scanfn* scanfn; /* Pointer to parent arg_xxx scan function */

arg_checkfn* checkfn; /* Pointer to parent arg_xxx check function */

arg_errorfn* errorfn; /* Pointer to parent arg_xxx error function */

void* priv; /* Pointer to private header data for use by arg_xxx functions */

} arg_hdr_t;

最基本的一个类型,所有的其他类型都包含这个类型。一一解释下里面的参数的含义:

  • shortopts: 参数的短名称,比如ls -a 中的a就是短名称;

  • longopts: 参数中的长名称,比如ls —all 中的all就是长名称;

  • datatype: 参数的数据类型有, , NULL, ,(时间类型传入format字符串),(rex类型传入匹配串),等;

  • glossary: 对于参数的描述;

  • mincount: 参数最少的个数(可以规定是否必须有参数比如设置为0为非必须,1…n为必须);

  • maxcount: 参数最多的个数,采用Unix风格的,如kernel.exe -l 1 -l 2 -l 3

  • 其他参数非必须。

arg_xxx结构体族

// 整数

struct arg_int

{

struct arg_hdr hdr;

int count;

int *ival;

};

// 文字

struct arg_lit

{

struct arg_hdr hdr;

int count;

};

// 双精度浮点数

struct arg_dbl

{

struct arg_hdr hdr;

int count;

double *dval;

};

// 字符串

struct arg_str

{

struct arg_hdr hdr;

int count;

const char **sval;

};

struct arg_rex

{

struct arg_hdr hdr;

int count;

const char **sval;

};

struct arg_file

{

struct arg_hdr hdr;

int count;

const char **filename;

const char **basename;

const char **extension;

};

struct arg_date

{

struct arg_hdr hdr;

const char *format;

int count;

struct tm *tm_val;

};

详细介绍 arg_int

struct arg_int

{

struct arg_hdr hdr;

int count;

int *ival;

};

结构体的第一个数据成员hdr保存了 Argtable3 库函数使用的私有数据。它包含参数的标签字符串等内容(可以理解为元数据)。

直接公开地访问这些数据是可以的,但很少需要这样做。

它的ival成员变量指向持有从命令行提取出的数组,count为数组的长度。ival 数组的存储在arg_int构造时分配。

这必须通过arg_int构造函数完成。

注意,你永远不应该自己手动实例化任何arg_xxx结构,而是始终使用提供的构造函数来分配结构,并在完成后使用 arg_freetable 释放它。

  • 举例

struct arg_int *s;

s = arg_intn(NULL, “scalar”, “”, 3, 5, “foo value”);

完成s后将指向一个包含5 个元素数组的内存块的结构体arg_int。

甚至,你还可以设置多个别名,短选项被赋予一串单个字符,而长选项被赋予一个逗号分隔的字符串。

例如:s = arg_intn("kKx", "scalar,foo", "<n>", 3, 5, "foo value");

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Vo3FZ9oz-1633800152784)(example.png)]

如图所示,该s->hdr结构保留对构造函数的字符串参数的引用等。

s->count变量初始化为零,因为它表示s->ival解析命令行后存储在数组中的有效值的数量。

s->ival数组的大小由s->hdr.maxcount给出。

  • 实例代码

// 引入 argtable3

#include “argtable3.h”

/* global arg_xxx structs */

struct arg_int *int_arrays;

struct arg_end *end;

int main(int argc, char *argv[]) {

/* the global arg_xxx structs are initialised within the argtable */

void *argtable[] = {

int_arrays = arg_intn(“a”, “array”, “”, 2, 3, “please input an integer”),

end = arg_end(20)

};

int exitcode = -1;

最后

学习视频:

大厂面试真题:

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

{

int_arrays = arg_intn(“a”, “array”, “”, 2, 3, “please input an integer”),

end = arg_end(20)

};

int exitcode = -1;

最后

学习视频:

[外链图片转存中…(img-gCU1JgyW-1715532428338)]

大厂面试真题:

[外链图片转存中…(img-myolNZ2l-1715532428339)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

  • 13
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值