C++ 查找变量参数列表的字符串格式说明符

C++ 查找变量参数列表的字符串格式说明符,c++,C++,我有一个日志函数,它调用我的记录器(spdlog)方法: template<typename... Args> void Log(const char* fmt, const Args&... args) { g_FileLogger->log(fmt, args...); } 模板 无效日志(常量字符*fmt, 常量参数(&…参数) { g_文件记录器->日志(fmt、args…); } 我想将我的记录器(spdlog,由g_FileLo

我有一个日志函数,它调用我的记录器(spdlog)方法:

template<typename... Args>
void Log(const char* fmt,
         const Args&... args)
{
    g_FileLogger->log(fmt, args...);
}
模板
无效日志(常量字符*fmt,
常量参数(&…参数)
{
g_文件记录器->日志(fmt、args…);
}
我想将我的记录器(spdlog,由g_FileLoggre表示)更改为另一个记录器。不幸的是,“fmt”字符串包含“{}”,它是变量“args”的占位符。我想用正确的格式说明符(%s,%zu,%d等)更改这些“{}”,与其他记录器一样,我必须指定正确的格式说明符

您能给我一个快速安全的解决方案来生成一个字符串,用变量的正确格式说明符替换“{}”吗


否则,spdlog是一个很好的日志API,但由于它的API已被破坏,我们决定选择另一个记录器,例如在Centos中,API是旧的,而在Gentoo中,它是新的,代码将无法编译。

创建一个
格式转换器
函数

template<typename... Args>
std::string format_converter(const char* fmt,
                             const Args&... args)
{...}

创建
格式转换器
功能

template<typename... Args>
std::string format_converter(const char* fmt,
                             const Args&... args)
{...}

创建
convert_format
函数,该函数将用指定的内容替换
{..}
。创建包含要替换的数据的
std::map
对象

#include <string>
#include <map>

std::string convert_format(const std::string& format, std::map<std::string, std::string> format_map) {
    string ret;
    for (int x = 0; x != format.size(); ++x)  {
        if (format[x] == '{') {
            std::string key;
            ++x;
            for (; x != format.size(); ++x) {
                if (format[x] == '}') {
                    auto itr = format_map.find(key);
                    if (itr != format_map.end()) {
                        ret += (*itr).second;
                    }
                    break;
                } else {
                    key.push_back(format[x]);
                }
            }
        } else {
            ret.push_back(format[x]);
        }
    }

    return ret;
}

EDIT:我认为您需要一个宏,该宏将变量的名称和值传递给函数
Log
创建
convert\u format
函数,该函数将用您指定的内容替换
{..}
。创建包含要替换的数据的
std::map
对象

#include <string>
#include <map>

std::string convert_format(const std::string& format, std::map<std::string, std::string> format_map) {
    string ret;
    for (int x = 0; x != format.size(); ++x)  {
        if (format[x] == '{') {
            std::string key;
            ++x;
            for (; x != format.size(); ++x) {
                if (format[x] == '}') {
                    auto itr = format_map.find(key);
                    if (itr != format_map.end()) {
                        ret += (*itr).second;
                    }
                    break;
                } else {
                    key.push_back(format[x]);
                }
            }
        } else {
            ret.push_back(format[x]);
        }
    }

    return ret;
}

编辑:我想您需要一个宏,该宏将变量的名称和值传递给函数
Log

您尝试过正则表达式替换吗?您尝试过正则表达式替换吗?我对模板不太熟悉,请给我一个使用类型字符串的格式转换器的简单代码。Thanks@Aminos你试过fmt库了吗?我不想使用它,因为当我在Ubuntu下尝试使用Spdlog(使用fmt)时,我不得不修改一个const变量的名称(在fmt的源文件中),该变量已经被一个define在别处使用(我不知道在哪里)。我不想在我正在打包的应用程序中处理此类问题(这也是我想使用spdlog以外的另一个“稳定”日志API的原因,我喜欢spdlog)。我不擅长使用模板,你能给我一个使用类型字符串的format_converter的简单代码吗。Thanks@Aminos你试过fmt库了吗?我不想使用它,因为当我在Ubuntu下尝试使用Spdlog(使用fmt)时,我不得不修改一个const变量的名称(在fmt的源文件中),该变量已经被一个define在别处使用(我不知道在哪里)。我不想在我正在打包的应用程序中处理这种问题(这也是我想使用另一个“稳定”的日志API而不是spdlog的原因,我喜欢spdlog)。
template<typename... Args>
void Log(const char* fmt,
         const Args&... args)
{
    // map that will contain the data.
    std::map<std::string, std::string> format_map;

    // IF you have an args named as number and a string
    // replaces {number} with %d
    format_map["number"] = "%d";

    // for replacing '{string}' with %s
    format_map["string"] = "%s"; // ... and so on

    auto new_fmt = convert_format(std::string(fmt), format_map);
    new_logger->log( new_fmt, args... );
}