【ArgParse】一个开源的入参解析库
项目地址:argtable3
本地验证:
-
编译构建
-
新增验证
// examples/skull.c #include "argtable3.h" int main(int argc, char **argv) { const char* progname = "skull"; struct arg_lit *help = arg_lit0("h", "help", "this is help info"); struct arg_lit *litn = arg_litn("l", "literal", 0, 5, "./progname -l --literal"); struct arg_int *intn = arg_intn("i", "integer", "<int>", 0, 5, "./program -i 10 -i 20 -i 30"); struct arg_dbl *dbln = arg_dbln("d", "double", "<double>", 0, 5, "./program -d 3.14 -d 2.718 -d 1.414"); struct arg_str *strn = arg_strn("s", "string", "<string>", 0, 5, "./program -s hello -s world"); struct arg_rex *rexn = arg_rexn("r", "regular", "^[A-Za-z0-9]+$", "<regex>", 0, 5, ARG_REX_ICASE, "./program -r [digit] -r [letters]"); struct arg_file *filen = arg_filen("f", "file", "<file>", 0, 5, "./program file1.txt file2.txt file3.txt"); struct arg_date *daten = arg_daten("a", "date", "%Y-%m-%d", "<date>", 0, 5, "./program -a 2023-09-01 -a 2023-09-02 -a 2023-09-03"); struct arg_end *end = arg_end(20); void* argtable[] = {help, litn, intn, dbln, strn, rexn, filen, daten, end}; int nerrors; int exitcode=0; /* verify the argtable[] entries were allocated sucessfully */ if (arg_nullcheck(argtable) != 0) { /* NULL entries were detected, some allocations must have failed */ printf("%s: insufficient memory\n", progname); exitcode=1; goto exit; } /* Parse the command line as defined by argtable[] */ nerrors = arg_parse(argc, argv, argtable); /* If the parser returned any errors then display them and exit */ if (nerrors > 0) { /* Display the error details contained in the arg_end struct.*/ arg_print_errors(stdout,end,progname); printf("Try '%s --help' for more information.\n", progname); exitcode=1; goto exit; } /* special case: '--help' takes precedence over error reporting */ if (help->count > 0) { printf("Usage: %s", progname); arg_print_syntax(stdout, argtable, "\n"); printf("Print certain system information. With no options, same as -s.\n\n"); arg_print_glossary(stdout, argtable," %-25s %s\n"); printf("\nReport bugs to <foo@bar>.\n"); exitcode=0; goto exit; } /* special case: '--version' takes precedence error reporting */ if (litn->count > 0) { printf("'%s' count: %d.\n", litn->hdr.glossary, litn->count); exitcode=0; goto exit; } if (intn->count > 0) { printf("'%s' count: %d.\n", intn->hdr.glossary, intn->count); for (int i = 0; i < intn->count; i++) { printf("Integer %d: %d\n", i+1, intn->ival[i]); } exitcode=0; goto exit; } if (dbln->count > 0) { printf("'%s' count: %d.\n", dbln->hdr.glossary, dbln->count); for (int i = 0; i < dbln->count; i++) { printf("Double %d: %lf\n", i+1, dbln->dval[i]); } exitcode=0; goto exit; } if (strn->count > 0) { printf("'%s' count: %d.\n", strn->hdr.glossary, strn->count); for (int i = 0; i < strn->count; i++) { printf("String %d: %s\n", i+1, strn->sval[i]); } exitcode=0; goto exit; } if (rexn->count > 0) { printf("'%s' count: %d.\n", rexn->hdr.glossary, rexn->count); for (int i = 0; i < rexn->count; i++) { printf("Regular %d: %s\n", i+1, rexn->sval[i]); } exitcode=0; goto exit; } if (filen->count > 0) { printf("'%s' count: %d.\n", filen->hdr.glossary, filen->count); for (int i = 0; i < filen->count; i++) { printf("File %d: %s\n", i+1, filen->filename[i]); } exitcode=0; goto exit; } if (daten->count > 0) { printf("'%s' count: %d.\n", daten->hdr.glossary, daten->count); for (int i = 0; i < daten->count; i++) { printf("Date %d: %04d-%02d-%02d\n", i+1, daten->tmval[i].tm_year, daten->tmval[i].tm_mon, daten->tmval[i].tm_mday); } exitcode=0; goto exit; } exit: /* deallocate each non-null entry in argtable[] */ arg_freetable(argtable,sizeof(argtable)/sizeof(argtable[0])); return exitcode; }
-
源码修改
实测月份少1,年份是基于1900
// src/arg_date.c char* arg_strptime(const char* buf, const char* fmt, struct tm* tm) { while ((c = *fmt) != '\0') { /* Clear `alternate' modifier prior to new conversion. */ alt_format = 0; /* Eat up white-space. */ if (isspace(c)) { while (isspace((int)(*bp))) bp++; fmt++; continue; } if ((c = *fmt++) != '%') goto literal; again: switch (c = *fmt++) { case 'm': /* The month. */ LEGAL_ALT(ALT_O); if (!(conv_num(&bp, &i, 1, 12))) return (0); /* tm->tm_mon = i- 1; @skull #2023-9-14 10:18:34 */ tm->tm_mon = i; break; case 'Y': /* The year. */ LEGAL_ALT(ALT_E); if (!(conv_num(&bp, &i, 0, 9999))) return (0); /* tm->tm_year = i - TM_YEAR_BASE; @skull #2023-9-14 10:19:59 */ tm->tm_year = i; break;
-
执行
再牛逼的梦想也架不住傻逼似的坚持
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧