cmdline学习

1、简介

cmdline是一个非常好用的C++命令行解析器,使用模板书写,只有一个文件,很容易集成到自己的程序。使用也非常简单。

2、使用

#include "cmdline.h"
int main(int argc, char *argv[])
{
    //1、首先创建一个命令行解析器
    cmdline::parser a;

    //2、制定输入参数和限制条件
    //有几种用法我们一一介绍

    //第一个参数:长名字
    //第二个参数:短名字
    //第三个参数:参数描述
    //第四个参数:bool值,该参数是否必须存在
    //第五个参数:默认值
    a.add<string>("host", ‘h‘, "host name", true, "");

    //第六个参数:用来对参数加入额外的限制
    //这里端口号被限制为必须是1到65535区间的值,通过cmdline::range(1,65535)进行限制
    a.add<int>("port",'p',"port number",false,80,cmdline::range(1,65535));

    //cmdline::oneof()能够用来限制参数的可选项
    a.add<string>("type",'t', "protocol type", false, "http", cmdline::oneof<string>("http", "https", "ssh", "ftp"));

    //调用不带类型的add方法,相当于一个bool值
    a.add("gzip",'\0',"gzip .....");

    //3、传入命令行,进行分析,不符合时输出信息,退出程序。
    a.parse_check(argc,argv);
    //只有全部的参数符合上面制定的标准才可往下执行
    //假设输入--help 或者 -? 这种程序也会退出,但是输出的是帮助信息

    //4、获取输入的参数值
    auto type = a.get<string>("type");
    auto host = a.get<string>("host");
    auto port = a.get<int>("port");
    //bool 值通过调用exsit()方法来判断
    bool isexist =  a.exist("gzip");
}

3、错误1 cxxabi.h提示错误

参考:https://blog.csdn.net/chyuanrufeng/article/details/108847886

我在使用cmdline的时候,在gcc下编译都正常,但在MSVC环境下,是不能编译的,因为缺少头文件cxxabi.h,这个头文件MSVC是没有的。

原因分析

C/C++语言在编译以后,函数和数据类型的名字会被编译器修改,改成编译器内部的名字,这个名字会在链接的时候用到。如果用backtrace之类的函数打印堆栈时,显示的就是被编译器修改过的名字,比如说_Z3foov , 数据类型名称也是一样,比如在gcc下double的类型内部名字就变成了’d’,

gcc下调用typeid(double).name()返回的结果是’d’ 。

那么这个函数或类型真实的名字是什么呢? 如何在运行时获取类型或函数真实的名称呢? 上面这个demangle函数中调用的abi::cxa_demangle的作用就是将编译器内部使用的名字反向转换(demangle)为源代码中定义的名字。 MSVC为什么没有提供abi::cxa_demangle类似的功能呢?因为MSVC编译器编译的代码typeid返回的是demangle后的结果。 也就是说,在MSVC下typeid(double).name()返回的就是”double”。所以不需要类似的功能。

解决办法

找到原因就好办了,只需要用宏定义改造代码就好了,只需要修改两处代码:

1.修改#include部分

#ifdef __GNUC__
#include <cxxabi.h>
#endif

2.修改demangle函数,当编译器为MSVC时直接将输入参数返回

static inline std::string demangle(const std::string &name)
{
#ifdef _MSC_VER
    return name;    // 为MSVC编译器时直接返回name
#elif defined(__GNUC__) 
    int status=0;
    char *p=abi::__cxa_demangle(name.c_str(), 0, 0, &status);
    std::string ret(p);
    free(p);
    return ret;
#else               // 其他不支持的编译器需要自己实现这个方法
    #error unexpected c complier (msc/gcc), Need to implement this method for demangle
#endif
}

4、错误2 std::max使用的位置错误

error C2589: '(' : illegal token on right side of '::' error C2143: syntax error : missing ';' before '::'

解决方式(两种)修改如下面

max_width = (std::max)(max_width, (ordered[i]->name().length())); max_width=std::max< size_t>(max_width, ordered[i]->name().length());

results matching ""

    No results matching ""