关于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
相关产品推荐
相关产品推荐

