查找可变参数列表的字符串格式指定符
finding string format specifiers of variable argument list
我具有调用我的logger(spdlog(方法的该日志功能:
template<typename... Args>
void Log(const char* fmt,
const Args&... args)
{
g_FileLogger->log(fmt, args...);
}
我想将我的记录器(由g_fileloggre代表(更改为另一个记录器。不幸的是," fmt"字符串包含" {}",它是变量的占位符" args"。我想通过正确的格式指定符(%s,%zu,%d等...(更改这些" {}">
您可以给我一个快速安全的解决方案,以生成一个用变量的正确格式替换" {}"的字符串。
否则,SPDLog是一个很棒的日志记录API,但是由于其API已损坏,我们决定选择另一个记录器,例如,在CentOS中,API旧了,而在Gentoo中,它是更新的,代码不会编译。
创建format_converter
函数
template<typename... Args>
std::string format_converter(const char* fmt,
const Args&... args)
{...}
解析FMT字符串并根据参数进行转换。
然后修改您的功能:
template<typename... Args>
void Log(const char* fmt,
const Args&... args)
{
auto new_fmt = format_converter(fmt, args...);
new_logger->log( new_fmt, args... );
}
编辑:
在format_converter
中,模板功能可用于将参数类型转换为字符串。例如:
template< typename T >
const char* type_string( const T ); // primary template
const char* type_string( const char* ) // overload for c-string
{
return "%s";
}
template<>
const char* type_string< double >( const double ) // partial specialization for double
{
return "%d";
}
template<>
const char* type_string< int >( const int ) // partial specialization for int
{
return "%i";
}
// .....
创建convert_format
函数,该功能将用您指定的内容替换{..}
。创建一个包含用于替换数据的std::map<std::string, std::string>
对象。
#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
函数修改为:
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... );
}
编辑:我认为您需要一个将变量的名称和值传递给函数Log
的宏。
相关文章:
- 是否可以从格式字符串中检索"width"
- 我应该如何从 stdin C++ 中读取可变长度的格式字符串?
- 从用户定义的类生成格式字符串?
- 如何连接格式字符串?
- 如何在C++中将"%Y%m%d"格式字符串转换为time_t变量?
- CPPCHECK C++成员函数上的格式字符串
- scanf() 语句中"%*[^n]"的格式字符串指示什么?分配抑制器 (*) 和否定扫描集 ([^) 如何协同工作?
- 自定义 {fmt} 格式化函数,具有编译时格式字符串检查功能
- '|' scanf 格式字符串是什么意思
- 如何使用 msgfmt 验证格式字符串中的位置表示法占位符
- sscanf_s:格式字符串"%d"需要类型为"int *"的参数,但可变参数 4 的类型为"WORD *"
- C4477: 'fprintf' :格式字符串 '%s' 需要类型为"char *"的参数,但可变参数 1 的类型为"int *"
- 如何使用OpenSSL API从其PEM格式字符串中读取RSA公钥
- C 格式字符串宏
- C++等效于 C 的格式字符串
- 如何使用 C++ 中的 rapidjson 库从 json 格式字符串中获取值
- _vsnprintf和_vsnprintf_s的格式字符串中的可用百分比字符
- 如何将格式字符串发送到iostream
- 跨平台格式字符串
- 使用 swprintf() 打印"0x0"的格式字符串应该是什么?