C++ fmtlib:如何将双精度转换为现有 wchar_t 缓冲区?
C++ fmtlib : How to convert a double to existing wchar_t buffer?
我正在考虑从 snprintf 及其同类产品过渡到 fmtlib。
想象一下这个虚构的代码:
class CFoo
{
size_t m_szLen{0};
wchar_t m_pwcDst[123]{};
...
public:
void Bar(double dValue, uint8 u8TotDecimals)
{
m_szLen += swprintf_s(&m_pwcDst[m_szLen], _countof(m_pwcDst)-m_szLen, L"%.*f", u8TotDecimals, dValue);
}
};
如何在不复制 std::wstring 或 fmt_memory_buffer 的情况下将其转换为 fmtlib?
所以,我希望 fmt::format_to 使用我现有的缓冲区。
fmtlib 中最接近 swprintf_s()
的函数是 fmt::format_to_n()
。但是,它 returns 会 写入的字符数,因此您必须小心使用它。这是它的样子:
void CFoo::Add(double dValue, uint8 u8TotDecimals)
{
if(pwcSrc) {
auto space_left = _countof(m_pwcDst) - m_u32Len;
auto result = fmt::format_to_n(&m_pcwDst, space_left, "{:.{}f}", u8TotDecimals, dValue);
m_u32Len += std::min(result.size, space_left);
}
}
但是,如果您想以正确的 C++ 方式做事,请尝试查看是否可以将目标缓冲区更改为 std::wstring
,然后直接添加到其中,如下所示:
void CFoo::Add(double dValue, uint8 u8TotDecimals)
{
if(pwcSrc)
m_pwsDst += fmt::format(L"{:.{}f}", u8TotDecimals, dValue);
}
它并不像我希望的那样 simple/clear,所以很遗憾。但是,这可能会满足我的要求:
class CFoo
{
size_t m_szLen{0};
wchar_t m_pwcDst[123]{};
...
public:
void Bar(double dValue, uint8 u8TotDecimals)
{
m_pwcDst[m_szLen += std::min(_countof(m_pwcDst)-m_szLen-1, fmt::format_to_n(&m_pwcDst[m_szLen], _countof(m_pwcDst)-m_szLen, FMT_STRING(L"{:.{}f}"), dValue, u8TotDecimals).size)] = L'[=10=]';
}
};
{fmt} 等价于 swprintf_s
是 format_to_n
,可以按如下方式使用:
auto result = fmt::format_to_n(buffer, buffer_size, "{:.{}}", value, precision);
在您的示例中,value
是 dValue
,precision
是 u8TotDecimals
。 result.out
将为您提供指向输出末尾的指针和 result.size
如果输出未被截断(类似于 snprintf
)的总输出大小。
我正在考虑从 snprintf 及其同类产品过渡到 fmtlib。 想象一下这个虚构的代码:
class CFoo
{
size_t m_szLen{0};
wchar_t m_pwcDst[123]{};
...
public:
void Bar(double dValue, uint8 u8TotDecimals)
{
m_szLen += swprintf_s(&m_pwcDst[m_szLen], _countof(m_pwcDst)-m_szLen, L"%.*f", u8TotDecimals, dValue);
}
};
如何在不复制 std::wstring 或 fmt_memory_buffer 的情况下将其转换为 fmtlib? 所以,我希望 fmt::format_to 使用我现有的缓冲区。
fmtlib 中最接近 swprintf_s()
的函数是 fmt::format_to_n()
。但是,它 returns 会 写入的字符数,因此您必须小心使用它。这是它的样子:
void CFoo::Add(double dValue, uint8 u8TotDecimals)
{
if(pwcSrc) {
auto space_left = _countof(m_pwcDst) - m_u32Len;
auto result = fmt::format_to_n(&m_pcwDst, space_left, "{:.{}f}", u8TotDecimals, dValue);
m_u32Len += std::min(result.size, space_left);
}
}
但是,如果您想以正确的 C++ 方式做事,请尝试查看是否可以将目标缓冲区更改为 std::wstring
,然后直接添加到其中,如下所示:
void CFoo::Add(double dValue, uint8 u8TotDecimals)
{
if(pwcSrc)
m_pwsDst += fmt::format(L"{:.{}f}", u8TotDecimals, dValue);
}
它并不像我希望的那样 simple/clear,所以很遗憾。但是,这可能会满足我的要求:
class CFoo
{
size_t m_szLen{0};
wchar_t m_pwcDst[123]{};
...
public:
void Bar(double dValue, uint8 u8TotDecimals)
{
m_pwcDst[m_szLen += std::min(_countof(m_pwcDst)-m_szLen-1, fmt::format_to_n(&m_pwcDst[m_szLen], _countof(m_pwcDst)-m_szLen, FMT_STRING(L"{:.{}f}"), dValue, u8TotDecimals).size)] = L'[=10=]';
}
};
{fmt} 等价于 swprintf_s
是 format_to_n
,可以按如下方式使用:
auto result = fmt::format_to_n(buffer, buffer_size, "{:.{}}", value, precision);
在您的示例中,value
是 dValue
,precision
是 u8TotDecimals
。 result.out
将为您提供指向输出末尾的指针和 result.size
如果输出未被截断(类似于 snprintf
)的总输出大小。