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

关于fmt::format库带符号数值格式化结果不符的技术问询

关于fmt::format格式化负数的输出疑问
#include <iostream>
#include <cstdint>
#include <fmt/core.h>

using namespace std;

int main(int argc, char **argv)
{
    cout<<"Expected: '       -10'\n      got:'"<<fmt::format("{:>10d}",-10)<<"'\n";
    cout<<"Expected: '-000000010'\n      got:'"<<fmt::format("{:>010d}",-10)<<"'\n";

    cout<<"Expected: '   -10.457'\n      got:'"<<fmt::format("{:>10.3f}",-10.456789)<<"'\n";
    cout<<"Expected: '-00010.457'\n      got:'"<<fmt::format("{:>010.3f}",-10.456789)<<"'\n";

    return 0;
}

上述代码展示了我期望fmt::format库输出的「实用」格式化结果,但实际输出却与预期不同。请问这是库的错误,还是存在支持该输出的合理原因?

输出结果依赖于库版本,即使最新版本的输出也不符合我的预期(我认为多数人会认同我的预期)。

以下是部分版本的输出:

Expected: '       -10'
      got:'       -10' 
Expected: '-000000010'
      got:'0000000-10' 
Expected: '   -10.457'
      got:'   -10.457' 
Expected: '-00010.457'
      got:'000-10.457'

最新版本的输出:

Expected: '       -10'
      got:'       -10'
Expected: '-000000010'
      got:'       -10'
Expected: '   -10.457'
      got:'   -10.457'
Expected: '-00010.457'
      got:'   -10.457'

解答

这不是fmt库的错误,而是它遵循了Python格式化规范(fmt的设计参考了Python的str.format),同时也和C++标准库的行为保持一致。

核心原因

  • 对齐与填充的优先级规则:当使用>右对齐加0填充时,Python风格的格式化会把负号放在填充的0之外——宽度10仅指代数字部分的长度,符号会额外占用位置。若想让负号紧跟数字、前导0补在符号与数字之间,需要使用=对齐符,它的作用就是将符号放在填充字符和数字内容之间。
  • 最新版本的行为对齐:最新版fmt调整了{:>010d}这类写法的输出,和C标准库printf的行为对齐——printf("%10d", -10)会输出 -10,而非带前导0的格式,这是因为C标准中整数格式的0填充不会覆盖有符号数的符号位。

实现预期输出的方法

改用=对齐符即可得到你想要的结果:

// 输出 '-000000010'
fmt::format("{:=010d}", -10);
// 输出 '-00010.457'
fmt::format("{:=010.3f}", -10.456789);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 09:05:55