-1

我正在考虑从 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 使用我现有的缓冲区。

4

3 回答 3

0

swprintf_s()fmtlib 中最接近的函数是fmt::format_to_n(). 但是,它会返回将要写入的字符数,因此您必须小心使用它。这是它的外观:

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++ 方式做事,请尝试查看是否可以将目标缓冲区更改为 a std::wstring,然后直接添加到该缓冲区,如下所示:

void CFoo::Add(double dValue, uint8 u8TotDecimals)
{
    if(pwcSrc)
        m_pwsDst += fmt::format(L"{:.{}f}", u8TotDecimals, dValue);
}
于 2020-03-31T09:49:16.493 回答
0

它不像我希望的那样简单/清晰,所以这很遗憾。但是,这可能会做我想要的:

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'\0';
  }
};
于 2020-03-31T13:58:02.760 回答
0

{fmt} 的等价物swprintf_sisformat_to_n可以如下使用:

auto result = fmt::format_to_n(buffer, buffer_size, "{:.{}}", value, precision);

在您的示例value中 isdValueprecisionis u8TotDecimals。如果输出未被截断(类似于) result.out,将为您提供指向输出结尾的指针和总输出大小。result.sizesnprintf

于 2020-04-01T21:29:25.270 回答