You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

fmt::sprintf的正确使用方法是什么?替换sprintf后代码为何失效?

错误原因

  • 你混淆了C标准库sprintf和fmt库fmt::sprintf的接口约定:
    • C标准库sprintf的第一个参数是用于存储格式化结果的目标缓冲区地址
    • fmt::sprintf不需要传入目标缓冲区,它的返回值是格式化完成的std::string对象
  • 你的替换代码既没有把name数组作为输出目标传入,也没有接收fmt::sprintf的返回值,格式化后的结果没有被存储到name数组中,原有逻辑依赖的name变量完全没有被赋值,因此无法正常运行。

正确使用方式

方案1:直接使用fmt::sprintf返回值(更推荐,无缓冲区溢出风险)

不需要预先定义固定长度的char数组,直接接收返回的std::string即可:

auto type = actor->GetName();
std::string name;
if (type.find("AI") != std::string::npos) {
    name = fmt::sprintf("AI [%dm]", dist);
}
// 后续如果需要C风格字符串,调用name.c_str()即可

方案2:适配原有char数组逻辑

如果后续代码必须依赖固定长度的char name[0x64]定义,可以使用fmt::format_to_n接口写入预分配的缓冲区:

auto type = actor->GetName();
char name[0x64];
if (type.find("AI") != std::string::npos) {
    // 写入缓冲区,预留最后1位存放终止符
    auto write_res = fmt::format_to_n(name, sizeof(name) - 1, "AI [%dm]", dist);
    // 手动添加字符串终止符
    *write_res.out = '\0';
}

注意事项

  • 使用fmt相关接口需要提前引入对应头文件:#include <fmt/sprintf.h>(用fmt::sprintf时)、#include <fmt/format.h>(用fmt::format_to_n时)
  • fmt::sprintf默认会做格式字符串和参数的类型校验,相比C标准库sprintf安全性更高,不会出现类型不匹配导致的未定义行为。

内容的提问来源于stack exchange,提问作者user17198097

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 19:24:04