fmt::sprintf的正确使用方法是什么?

What is the correct way to use fmt::sprintf?

我正在努力优化我的软件,为此我需要改变我存储和绘制东西的方式。

许多人说 fmt 在做这些事情时比 iostream 快得多,但我坐在这里并试图了解我做错了什么。

旧代码有效:

auto type = actor->GetName();
char name[0x64];
if (type.find("AI") != std::string::npos)
sprintf(name, "AI [%dm]", dist);

新的不是:

auto type = actor->GetName();
char name[0x64];
if (type.find("AI") != std::string::npos)
fmt::sprintf("AI [%dm]", dist);

我做错了什么?

正如评论中提到的 @NathanPiersonfmt::sprintf() return 一个 std::string,你忽略了。 fmt::sprintf() 不会填充 char[] 缓冲区(并不是说你正在将一个缓冲区传递给它,就像你使用 ::sprintf() 一样)。

改变这个:

char name[0x64];
fmt::sprintf("AI [%dm]", dist);

为此:

std::string name = fmt::sprintf("AI [%dm]", dist);

然后您可以根据需要使用name。如果您需要将它传递给需要 (const) char* 的函数,您可以为此目的使用 name.c_str()name.data()

Many people say that fmt is way faster than iostream at doing those things, yet I'm sitting here and trying to understand what I did wrong.

除了雷米·勒博的正确答案外,还有一点。您提到速度是一个考虑因素。在这种情况下,您可能希望避免构造 std::string,并使用 fmt::format_to_n()(或 std::format_to_n)直接格式化到您的字符缓冲区中:

auto type = actor->GetName();
char name[0x64];
if (type.find("AI") != std::string::npos) {
    fmt::format_to_n(name, 0x64, "AI [{}m]", dist);
}

不幸的是,我认为 fmt 没有针对现有缓冲区的函数 并且 使用 printf 格式说明符。