ksargv解析命令行参数
V0.0.3.20210623
项目简介
介绍ksargv解析命令行参数步骤
正文
- 查看示例代码
void template_version(e_argv_type* argv, s_ksargv_value* values, unsigned int values_count, e_argv_erro erro);
char* version_option[] = {"-v", "-version", NULL};
e_argv_type version_type[] = {ARGV_STRING, ARGV_END};
void template_ip_port(e_argv_type* argv, s_ksargv_value* values, unsigned int values_count, e_argv_erro erro);
char* ip_port_option[] = {"-ip", NULL};
e_argv_type ip_port_type[] = {ARGV_STRING, ARGV_INT, ARGV_END};
void template_am_i_great(e_argv_type* argv, s_ksargv_value* values, unsigned int values_count, e_argv_erro erro);
char* am_i_great_option[] = {"-g", "-great", NULL};
e_argv_type am_i_great_type[] = {ARGV_BOOL, ARGV_END};
void template_score(e_argv_type* argv, s_ksargv_value* values, unsigned int values_count, e_argv_erro erro);
char* score_option[] = {"-s", "-score", NULL};
e_argv_type score_type[] = {ARGV_DOUBLE, ARGV_END};
void template_keep(e_argv_type* argv, s_ksargv_value* values, unsigned int values_count, e_argv_erro erro);
char* keep_option[] = {"-k", "-keep", NULL};
e_argv_type keep_type[] = {ARGV_END};
s_ksargv_elems argv_options[] =
{
{
.option = version_option,
.args = version_type,
.function = template_version,
},
{
.option = ip_port_option,
.args = ip_port_type,
.function = template_ip_port,
},
{
.option = am_i_great_option,
.args = am_i_great_type,
.function = template_am_i_great,
},
{
.option = score_option,
.args = score_type,
.function = template_score,
},
{
.option = keep_option,
.args = keep_type,
.function = template_keep,
},
};
以argv_options 数组看,数组存储三个元素,option是字符串指针,描述命令行中输入的命令名称,args描述需要接受的命令行参数,同时也表示了接收的命令行参数数量。function函数是将命令行解析的结果回调函数,直接查看ksargv中的说明即可
/**
* argv from <iksargv_parse_argv> argv
* values is array store values, if something erro, it will be NULL, and values_count will be zero
* values_count values array count, if something erro, it will be NULL, and values_count will be zero
* erro store why this function is erro, if there is no erro, it will be set ARGV_ERRO_NONE, when
* it be set ARGV_ERRO, mybe you should check ksargv source code or connect coder
*/
typedef void (*f_ksargv_function)(e_argv_type* argv, s_ksargv_value* values, unsigned int values_count, e_argv_erro erro);
存储字符串数组和不定长数组的结构体方法中,没有好主意可以直接初始化,只好提前定义好数组,在结构体初始化时使用数组指针,如有更简单的技巧请联系作者修改
-
示例代码的主函数只有两行
int main(int argc, char** argv) { ksargv_parse_argv(argv, argv_options, sizeof(argv_options) / sizeof(s_ksargv_elems)); dbg_print_mem(); }
第一行是解析命令行,第二行是调试使用,可以打印出动态内存申请次数,如果申请和释放次数是一样的,输出0
-
解析主函数
int ksargv_parse_argv(char** argv, s_ksargv_elems* elems, unsigned int elems_count) { if(argv[0] == NULL || argv[1] == NULL || elems_count == 0) return 0; s_ksargv_elems_status* status = KSARGV_MALLOC(sizeof(s_ksargv_elems_status) * elems_count); if(status == NULL) { errno = ENOMEM; return -1; } memset(status, 0, sizeof(s_ksargv_elems_status) * elems_count); for(int i = 1; argv[i] != NULL; i++) { int elem_index; if((elem_index = ksargv_parse_argv_get_elem_index(argv[i], status, elems, elems_count)) >= 0) { status[elem_index].select = true; int args_count = ksargv_parse_argv_get_elem_argv_count(elems[elem_index].args); if(args_count == 0) /* this option do not need args */ elems[elem_index].function(elems[elem_index].args, NULL, 0, ARGV_ERRO_NONE); else { /* ready */ s_ksargv_value* values = KSARGV_MALLOC(sizeof(s_ksargv_value) * args_count); if(values == NULL) { elems[elem_index].function(elems[elem_index].args, NULL, 0, ARGV_ERRO_LESS_ARGS); errno = ENOMEM; goto fall; } /* loop, convert argv */ for(int arg_index = 0; arg_index < args_count; arg_index++) { if(argv[i + 1] == NULL) { KSARGV_FREE(values); elems[elem_index].function(elems[elem_index].args, NULL, 0, ARGV_ERRO_LESS_ARGS); errno = ERESTART; goto fall; } bool res = true; values[arg_index].type = elems[elem_index].args[arg_index]; switch(elems[elem_index].args[arg_index]) { case ARGV_STRING: values[arg_index].value.str = argv[++i]; break; case ARGV_INT: values[arg_index].value.num_i = ksargv_parse_argv_get_int(argv[++i], &res); break; case ARGV_BOOL: values[arg_index].value.num_b = ksargv_parse_argv_get_bool(argv[++i], &res); break; case ARGV_DOUBLE: values[arg_index].value.num_d = ksargv_parse_argv_get_double(argv[++i], &res); break; default: break; } if(res == false) { KSARGV_FREE(values); elems[elem_index].function(elems[elem_index].args, NULL, 0, ARGV_ERRO_LESS_ARGS); errno = ERESTART; goto fall; } } /* done, send */ elems[elem_index].function(elems[elem_index].args, values, args_count, ARGV_ERRO_NONE); KSARGV_FREE(values); } } } KSARGV_FREE(status); return 0; fall: KSARGV_FREE(status); return -1; }
- 首先将会申请内存存储状态,状态结构体中只含有一个命令行命令是否被选中过,如-a,确保一段-a只执行一次,应该不会有需要-a执行多次的需求吧,不会吧 不会吧 不会吧
- 接下来遍历命令行的argv 逐个判断是否有现成的示例程序数组option字段
- 将遍历得到的结果,根据示例程序的argv按照格式保存下来,如果格式不对,立刻退出,并回调到function函数,通知出现了错误。
使用说明
维护说明
注意
关于作者
Autho: KiraSkyler
Email: kiraskyler@outlook.com / kiraskyler@qq.com
贡献者/贡献组织
鸣谢
版权信息
该项目签署了GPL 授权许可,详情请参阅官网
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see https://www.gnu.org/licenses/.
更新日志
- V0.0.0.20210101