我正在寻找一种使用可变大小的变量向量格式化字符串的方法。您建议这样做的最好方法是什么?
我已经知道std :: snprintf和std :: vsnprintf,但是不幸的是,没有一个可以解决我的问题。同样,使用递归模板的解决方案对我也不起作用,因为我不能依赖在编译时完全定义输入格式。
这是我要实现的功能的示例接口。
event.preventDefault()
示例输入和输出:
event.stopPropagation()
format_variable_size将返回
std::string format_variable_size(const char* format, const std::vector<int>& in) {
std::string out{};
....
return out;
}
另一个例子:
const char* format = "My first int is %d, my second int is: %d, my float is: %d";
std::vector<int> in = {1,2,3};
format_variable_size将返回
out = "My first int is 1, my second int is: 2, my float is: 3"
谢谢
答案 0 :(得分:1)
如果您不反对使用fmt,我认为以下方法可能会起作用:
#include <numeric>
std::string format_variable_size(const char* fmt, std::vector<int> args){
return std::accumulate(
std::begin(args),
std::end(args),
std::string{fmt},
[](std::string toFmt, int arg){
return fmt::format(toFmt, arg);
}
);
}
std::vector<int> v = {1,2,3};
std::cout << format_variable_size("[{}, {}, {}]\n", v);
答案 1 :(得分:0)
如果您使用的唯一说明符是%d
,则可以轻松地执行循环并用向量中的值手动替换。另外,您可以考虑定义自己的替换令牌(例如###
)以简化解析。
此外,如果您可以使用相对较小的向量大小(例如最大数目),则可以执行以下操作:
std::vector<int> copy(in);
copy.resize(10);
std::snprintf(buffer, buffer_size,
copy[0], copy[1], copy[2], copy[3], copy[4],
copy[5], copy[6], copy[7], copy[8], copy[9]);
%d
的数量大于输入向量且不超过副本的大小,则将输出额外的%d,其值为0。答案 2 :(得分:0)
不是很好的解决方案,因为我们在编译时无法获得std::vector
的大小:
template <std::size_t... I>
std::string
format_variable_size_impl(const char* format, const std::vector<int>& in,
std::index_sequence<I...>)
{
// Determine the necessary buffer size
auto size = std::snprintf(nullptr, 0, format, in[I]...);
std::string out(size + 1, 0);
std::sprintf(out.data(), format, in[I]...);
return out;
}
std::string
format_variable_size(const char* format, const std::vector<int>& in)
{
if (in.size() == 0)
return format;
if (in.size() == 1)
return format_variable_size_impl(format, in, std::make_index_sequence<1>{});
if (in.size() == 2)
return format_variable_size_impl(format, in, std::make_index_sequence<2>{});
if (in.size() == 3)
return format_variable_size_impl(format, in, std::make_index_sequence<3>{});
if (in.size() == 4)
return format_variable_size_impl(format, in, std::make_index_sequence<4>{});
if (in.size() == 5)
return format_variable_size_impl(format, in, std::make_index_sequence<5>{});
// ...
}